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 = MsiDatabaseCommit( hdb );
100 ok( res == ERROR_SUCCESS , "Failed to commit database\n" );
102 res = MsiCloseHandle( hdb );
103 ok( res == ERROR_SUCCESS , "Failed to close database\n" );
105 res = MsiOpenDatabase( msifile, MSIDBOPEN_DIRECT, &hdb );
106 ok( res == ERROR_SUCCESS , "Failed to open database\n" );
108 res = MsiCloseHandle( hdb );
109 ok( res == ERROR_SUCCESS , "Failed to close database\n" );
111 res = MsiOpenDatabase( msifile, MSIDBOPEN_TRANSACT, &hdb );
112 ok( res == ERROR_SUCCESS , "Failed to open database\n" );
114 res = MsiCloseHandle( hdb );
115 ok( res == ERROR_SUCCESS , "Failed to close database\n" );
116 ok( INVALID_FILE_ATTRIBUTES != GetFileAttributes( msifile ), "database should exist\n");
118 /* MSIDBOPEN_CREATE deletes the database if MsiCommitDatabase isn't called */
119 res = MsiOpenDatabase( msifile, MSIDBOPEN_CREATE, &hdb );
120 ok( res == ERROR_SUCCESS , "Failed to open database\n" );
122 ok( INVALID_FILE_ATTRIBUTES != GetFileAttributes( msifile ), "database should exist\n");
124 res = MsiCloseHandle( hdb );
125 ok( res == ERROR_SUCCESS , "Failed to close database\n" );
127 ok( INVALID_FILE_ATTRIBUTES == GetFileAttributes( msifile ), "database should exist\n");
129 res = MsiOpenDatabase( msifile, MSIDBOPEN_CREATE, &hdb );
130 ok( res == ERROR_SUCCESS , "Failed to open database\n" );
132 res = MsiDatabaseCommit( hdb );
133 ok( res == ERROR_SUCCESS , "Failed to commit database\n" );
135 ok( INVALID_FILE_ATTRIBUTES != GetFileAttributes( msifile ), "database should exist\n");
137 res = MsiCloseHandle( hdb );
138 ok( res == ERROR_SUCCESS , "Failed to close database\n" );
140 res = DeleteFile( msifile2 );
141 ok( res == TRUE, "Failed to delete database\n" );
143 res = DeleteFile( msifile );
144 ok( res == TRUE, "Failed to delete database\n" );
147 static UINT do_query(MSIHANDLE hdb, const char *query, MSIHANDLE *phrec)
155 /* open a select query */
156 r = MsiDatabaseOpenView(hdb, query, &hview);
157 if (r != ERROR_SUCCESS)
159 r = MsiViewExecute(hview, 0);
160 if (r != ERROR_SUCCESS)
162 ret = MsiViewFetch(hview, phrec);
163 r = MsiViewClose(hview);
164 if (r != ERROR_SUCCESS)
166 r = MsiCloseHandle(hview);
167 if (r != ERROR_SUCCESS)
172 static UINT run_query( MSIHANDLE hdb, MSIHANDLE hrec, const char *query )
177 r = MsiDatabaseOpenView(hdb, query, &hview);
178 if( r != ERROR_SUCCESS )
181 r = MsiViewExecute(hview, hrec);
182 if( r == ERROR_SUCCESS )
183 r = MsiViewClose(hview);
184 MsiCloseHandle(hview);
188 static UINT run_queryW( MSIHANDLE hdb, MSIHANDLE hrec, const WCHAR *query )
193 r = MsiDatabaseOpenViewW(hdb, query, &hview);
194 if( r != ERROR_SUCCESS )
197 r = MsiViewExecute(hview, hrec);
198 if( r == ERROR_SUCCESS )
199 r = MsiViewClose(hview);
200 MsiCloseHandle(hview);
204 static UINT create_component_table( MSIHANDLE hdb )
206 return run_query( hdb, 0,
207 "CREATE TABLE `Component` ( "
208 "`Component` CHAR(72) NOT NULL, "
209 "`ComponentId` CHAR(38), "
210 "`Directory_` CHAR(72) NOT NULL, "
211 "`Attributes` SHORT NOT NULL, "
212 "`Condition` CHAR(255), "
213 "`KeyPath` CHAR(72) "
214 "PRIMARY KEY `Component`)" );
217 static UINT create_custom_action_table( MSIHANDLE hdb )
219 return run_query( hdb, 0,
220 "CREATE TABLE `CustomAction` ( "
221 "`Action` CHAR(72) NOT NULL, "
222 "`Type` SHORT NOT NULL, "
223 "`Source` CHAR(72), "
224 "`Target` CHAR(255) "
225 "PRIMARY KEY `Action`)" );
228 static UINT create_directory_table( MSIHANDLE hdb )
230 return run_query( hdb, 0,
231 "CREATE TABLE `Directory` ( "
232 "`Directory` CHAR(255) NOT NULL, "
233 "`Directory_Parent` CHAR(255), "
234 "`DefaultDir` CHAR(255) NOT NULL "
235 "PRIMARY KEY `Directory`)" );
238 static UINT create_feature_components_table( MSIHANDLE hdb )
240 return run_query( hdb, 0,
241 "CREATE TABLE `FeatureComponents` ( "
242 "`Feature_` CHAR(38) NOT NULL, "
243 "`Component_` CHAR(72) NOT NULL "
244 "PRIMARY KEY `Feature_`, `Component_` )" );
247 static UINT create_std_dlls_table( MSIHANDLE hdb )
249 return run_query( hdb, 0,
250 "CREATE TABLE `StdDlls` ( "
251 "`File` CHAR(255) NOT NULL, "
252 "`Binary_` CHAR(72) NOT NULL "
253 "PRIMARY KEY `File` )" );
256 static UINT create_binary_table( MSIHANDLE hdb )
258 return run_query( hdb, 0,
259 "CREATE TABLE `Binary` ( "
260 "`Name` CHAR(72) NOT NULL, "
261 "`Data` CHAR(72) NOT NULL "
262 "PRIMARY KEY `Name` )" );
265 #define make_add_entry(type, qtext) \
266 static UINT add##_##type##_##entry( MSIHANDLE hdb, const char *values ) \
268 char insert[] = qtext; \
271 sz = strlen(values) + sizeof insert; \
272 query = HeapAlloc(GetProcessHeap(),0,sz); \
273 sprintf(query,insert,values); \
274 r = run_query( hdb, 0, query ); \
275 HeapFree(GetProcessHeap(), 0, query); \
279 make_add_entry(component,
280 "INSERT INTO `Component` "
281 "(`Component`, `ComponentId`, `Directory_`, "
282 "`Attributes`, `Condition`, `KeyPath`) VALUES( %s )")
284 make_add_entry(custom_action,
285 "INSERT INTO `CustomAction` "
286 "(`Action`, `Type`, `Source`, `Target`) VALUES( %s )")
288 make_add_entry(feature_components,
289 "INSERT INTO `FeatureComponents` "
290 "(`Feature_`, `Component_`) VALUES( %s )")
292 make_add_entry(std_dlls,
293 "INSERT INTO `StdDlls` (`File`, `Binary_`) VALUES( %s )")
295 make_add_entry(binary,
296 "INSERT INTO `Binary` (`Name`, `Data`) VALUES( %s )")
298 static void test_msiinsert(void)
300 MSIHANDLE hdb = 0, hview = 0, hrec = 0;
308 /* just MsiOpenDatabase should not create a file */
309 r = MsiOpenDatabase(msifile, MSIDBOPEN_CREATE, &hdb);
310 ok(r == ERROR_SUCCESS, "MsiOpenDatabase failed\n");
313 query = "CREATE TABLE `phone` ( "
314 "`id` INT, `name` CHAR(32), `number` CHAR(32) "
316 r = MsiDatabaseOpenView(hdb, query, &hview);
317 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
318 r = MsiViewExecute(hview, 0);
319 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n");
320 r = MsiViewClose(hview);
321 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n");
322 r = MsiCloseHandle(hview);
323 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
325 /* insert a value into it */
326 query = "INSERT INTO `phone` ( `id`, `name`, `number` )"
327 "VALUES('1', 'Abe', '8675309')";
328 r = MsiDatabaseOpenView(hdb, query, &hview);
329 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
330 r = MsiViewExecute(hview, 0);
331 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n");
332 r = MsiViewClose(hview);
333 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n");
334 r = MsiCloseHandle(hview);
335 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
337 query = "SELECT * FROM `phone` WHERE `id` = 1";
338 r = do_query(hdb, query, &hrec);
339 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n");
341 /* check the record contains what we put in it */
342 r = MsiRecordGetFieldCount(hrec);
343 ok(r == 3, "record count wrong\n");
345 r = MsiRecordIsNull(hrec, 0);
346 ok(r == FALSE, "field 0 not null\n");
348 r = MsiRecordGetInteger(hrec, 1);
349 ok(r == 1, "field 1 contents wrong\n");
351 r = MsiRecordGetString(hrec, 2, buf, &sz);
352 ok(r == ERROR_SUCCESS, "field 2 content fetch failed\n");
353 ok(!strcmp(buf,"Abe"), "field 2 content incorrect\n");
355 r = MsiRecordGetString(hrec, 3, buf, &sz);
356 ok(r == ERROR_SUCCESS, "field 3 content fetch failed\n");
357 ok(!strcmp(buf,"8675309"), "field 3 content incorrect\n");
359 r = MsiCloseHandle(hrec);
360 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
362 /* open a select query */
364 query = "SELECT * FROM `phone` WHERE `id` >= 10";
365 r = do_query(hdb, query, &hrec);
366 ok(r == ERROR_NO_MORE_ITEMS, "MsiViewFetch failed\n");
367 ok(hrec == 0, "hrec should be null\n");
369 r = MsiCloseHandle(hrec);
370 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
372 query = "SELECT * FROM `phone` WHERE `id` < 0";
373 r = do_query(hdb, query, &hrec);
374 ok(r == ERROR_NO_MORE_ITEMS, "MsiViewFetch failed\n");
376 query = "SELECT * FROM `phone` WHERE `id` <= 0";
377 r = do_query(hdb, query, &hrec);
378 ok(r == ERROR_NO_MORE_ITEMS, "MsiViewFetch failed\n");
380 query = "SELECT * FROM `phone` WHERE `id` <> 1";
381 r = do_query(hdb, query, &hrec);
382 ok(r == ERROR_NO_MORE_ITEMS, "MsiViewFetch failed\n");
384 query = "SELECT * FROM `phone` WHERE `id` > 10";
385 r = do_query(hdb, query, &hrec);
386 ok(r == ERROR_NO_MORE_ITEMS, "MsiViewFetch failed\n");
388 /* now try a few bad INSERT xqueries */
389 query = "INSERT INTO `phone` ( `id`, `name`, `number` )"
391 r = MsiDatabaseOpenView(hdb, query, &hview);
392 ok(r == ERROR_BAD_QUERY_SYNTAX, "MsiDatabaseOpenView failed\n");
394 /* construct a record to insert */
395 hrec = MsiCreateRecord(4);
396 r = MsiRecordSetInteger(hrec, 1, 2);
397 ok(r == ERROR_SUCCESS, "MsiRecordSetInteger failed\n");
398 r = MsiRecordSetString(hrec, 2, "Adam");
399 ok(r == ERROR_SUCCESS, "MsiRecordSetString failed\n");
400 r = MsiRecordSetString(hrec, 3, "96905305");
401 ok(r == ERROR_SUCCESS, "MsiRecordSetString failed\n");
403 /* insert another value, using a record and wildcards */
404 query = "INSERT INTO `phone` ( `id`, `name`, `number` )"
406 r = MsiDatabaseOpenView(hdb, query, &hview);
407 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
409 if (r == ERROR_SUCCESS)
411 r = MsiViewExecute(hview, hrec);
412 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n");
413 r = MsiViewClose(hview);
414 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n");
415 r = MsiCloseHandle(hview);
416 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
418 r = MsiCloseHandle(hrec);
419 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
421 r = MsiViewFetch(0, NULL);
422 ok(r == ERROR_INVALID_PARAMETER, "MsiViewFetch failed\n");
424 r = MsiDatabaseCommit(hdb);
425 ok(r == ERROR_SUCCESS, "MsiDatabaseCommit failed\n");
427 r = MsiCloseHandle(hdb);
428 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
430 r = DeleteFile(msifile);
431 ok(r == TRUE, "file didn't exist after commit\n");
434 typedef UINT (WINAPI *fnMsiDecomposeDescriptorA)(LPCSTR, LPCSTR, LPSTR, LPSTR, DWORD *);
435 static fnMsiDecomposeDescriptorA pMsiDecomposeDescriptorA;
437 static void test_msidecomposedesc(void)
439 char prod[MAX_FEATURE_CHARS+1], comp[MAX_FEATURE_CHARS+1], feature[MAX_FEATURE_CHARS+1];
445 hmod = GetModuleHandle("msi.dll");
446 pMsiDecomposeDescriptorA = (fnMsiDecomposeDescriptorA)
447 GetProcAddress(hmod, "MsiDecomposeDescriptorA");
448 if (!pMsiDecomposeDescriptorA)
451 /* test a valid feature descriptor */
452 desc = "']gAVn-}f(ZXfeAR6.jiFollowTheWhiteRabbit>3w2x^IGfe?CxI5heAvk.";
454 r = pMsiDecomposeDescriptorA(desc, prod, feature, comp, &len);
455 ok(r == ERROR_SUCCESS, "returned an error\n");
456 ok(len == strlen(desc), "length was wrong\n");
457 ok(strcmp(prod,"{90110409-6000-11D3-8CFE-0150048383C9}")==0, "product wrong\n");
458 ok(strcmp(feature,"FollowTheWhiteRabbit")==0, "feature wrong\n");
459 ok(strcmp(comp,"{A7CD68DB-EF74-49C8-FBB2-A7C463B2AC24}")==0,"component wrong\n");
461 /* test an invalid feature descriptor with too many characters */
462 desc = "']gAVn-}f(ZXfeAR6.ji"
463 "ThisWillFailIfTheresMoreThanAGuidsChars>"
464 "3w2x^IGfe?CxI5heAvk.";
466 r = pMsiDecomposeDescriptorA(desc, prod, feature, comp, &len);
467 ok(r == ERROR_INVALID_PARAMETER, "returned wrong error\n");
470 * Test a valid feature descriptor with the
471 * maximum number of characters and some trailing characters.
473 desc = "']gAVn-}f(ZXfeAR6.ji"
474 "ThisWillWorkIfTheresLTEThanAGuidsChars>"
475 "3w2x^IGfe?CxI5heAvk."
478 r = pMsiDecomposeDescriptorA(desc, prod, feature, comp, &len);
479 ok(r == ERROR_SUCCESS, "returned wrong error\n");
480 ok(len == (strlen(desc) - strlen("extra")), "length wrong\n");
483 r = pMsiDecomposeDescriptorA(desc, prod, feature, NULL, &len);
484 ok(r == ERROR_SUCCESS, "returned wrong error\n");
485 ok(len == (strlen(desc) - strlen("extra")), "length wrong\n");
488 r = pMsiDecomposeDescriptorA(desc, prod, NULL, NULL, &len);
489 ok(r == ERROR_SUCCESS, "returned wrong error\n");
490 ok(len == (strlen(desc) - strlen("extra")), "length wrong\n");
493 r = pMsiDecomposeDescriptorA(desc, NULL, NULL, NULL, &len);
494 ok(r == ERROR_SUCCESS, "returned wrong error\n");
495 ok(len == (strlen(desc) - strlen("extra")), "length wrong\n");
498 r = pMsiDecomposeDescriptorA(NULL, NULL, NULL, NULL, &len);
499 ok(r == ERROR_INVALID_PARAMETER, "returned wrong error\n");
500 ok(len == 0, "length wrong\n");
502 r = pMsiDecomposeDescriptorA(desc, NULL, NULL, NULL, NULL);
503 ok(r == ERROR_SUCCESS, "returned wrong error\n");
506 static UINT try_query_param( MSIHANDLE hdb, LPCSTR szQuery, MSIHANDLE hrec )
511 res = MsiDatabaseOpenView( hdb, szQuery, &htab );
512 if(res == ERROR_SUCCESS )
516 r = MsiViewExecute( htab, hrec );
517 if(r != ERROR_SUCCESS )
520 r = MsiViewClose( htab );
521 if(r != ERROR_SUCCESS )
524 r = MsiCloseHandle( htab );
525 if(r != ERROR_SUCCESS )
531 static UINT try_query( MSIHANDLE hdb, LPCSTR szQuery )
533 return try_query_param( hdb, szQuery, 0 );
536 static UINT try_insert_query( MSIHANDLE hdb, LPCSTR szQuery )
541 hrec = MsiCreateRecord( 1 );
542 MsiRecordSetString( hrec, 1, "Hello");
544 r = try_query_param( hdb, szQuery, hrec );
546 MsiCloseHandle( hrec );
550 static void test_msibadqueries(void)
557 /* just MsiOpenDatabase should not create a file */
558 r = MsiOpenDatabase(msifile, MSIDBOPEN_CREATE, &hdb);
559 ok(r == ERROR_SUCCESS, "MsiOpenDatabase failed\n");
561 r = MsiDatabaseCommit( hdb );
562 ok(r == ERROR_SUCCESS , "Failed to commit database\n");
564 r = MsiCloseHandle( hdb );
565 ok(r == ERROR_SUCCESS , "Failed to close database\n");
567 /* open it readonly */
568 r = MsiOpenDatabase(msifile, MSIDBOPEN_READONLY, &hdb );
569 ok(r == ERROR_SUCCESS , "Failed to open database r/o\n");
571 /* add a table to it */
572 r = try_query( hdb, "select * from _Tables");
573 ok(r == ERROR_SUCCESS , "query 1 failed\n");
575 r = MsiCloseHandle( hdb );
576 ok(r == ERROR_SUCCESS , "Failed to close database r/o\n");
578 /* open it read/write */
579 r = MsiOpenDatabase(msifile, MSIDBOPEN_TRANSACT, &hdb );
580 ok(r == ERROR_SUCCESS , "Failed to open database r/w\n");
582 /* a bunch of test queries that fail with the native MSI */
584 r = try_query( hdb, "CREATE TABLE");
585 ok(r == ERROR_BAD_QUERY_SYNTAX , "invalid query 2a return code\n");
587 r = try_query( hdb, "CREATE TABLE `a`");
588 ok(r == ERROR_BAD_QUERY_SYNTAX , "invalid query 2b return code\n");
590 r = try_query( hdb, "CREATE TABLE `a` ()");
591 ok(r == ERROR_BAD_QUERY_SYNTAX , "invalid query 2c return code\n");
593 r = try_query( hdb, "CREATE TABLE `a` (`b`)");
594 ok(r == ERROR_BAD_QUERY_SYNTAX , "invalid query 2d return code\n");
596 r = try_query( hdb, "CREATE TABLE `a` (`b` CHAR(72) )");
597 ok(r == ERROR_BAD_QUERY_SYNTAX , "invalid query 2e return code\n");
599 r = try_query( hdb, "CREATE TABLE `a` (`b` CHAR(72) NOT NULL)");
600 ok(r == ERROR_BAD_QUERY_SYNTAX , "invalid query 2f return code\n");
602 r = try_query( hdb, "CREATE TABLE `a` (`b` CHAR(72) NOT NULL PRIMARY)");
603 ok(r == ERROR_BAD_QUERY_SYNTAX , "invalid query 2g 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 2h return code\n");
608 r = try_query( hdb, "CREATE TABLE `a` (`b` CHAR(72) NOT NULL PRIMARY KEY)");
609 ok(r == ERROR_BAD_QUERY_SYNTAX , "invalid query 2i 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 2j 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 2k return code\n");
617 r = try_query( hdb, "CREATE TABLE `a` (`b` CHAR(72) NOT NULL PRIMARY KEY `b')");
618 ok(r == ERROR_BAD_QUERY_SYNTAX , "invalid query 2l return code\n");
620 r = try_query( hdb, "CREATE TABLE `a` (`b` CHA(72) NOT NULL PRIMARY KEY `b`)");
621 ok(r == ERROR_BAD_QUERY_SYNTAX , "invalid query 2m return code\n");
623 r = try_query( hdb, "CREATE TABLE `a` (`b` CHAR(-1) NOT NULL PRIMARY KEY `b`)");
624 ok(r == ERROR_BAD_QUERY_SYNTAX , "invalid query 2n return code\n");
626 r = try_query( hdb, "CREATE TABLE `a` (`b` CHAR(720) NOT NULL PRIMARY KEY `b`)");
627 ok(r == ERROR_BAD_QUERY_SYNTAX , "invalid query 2o return code\n");
629 r = try_query( hdb, "CREATE TABLE `a` (`b` CHAR(72) NOT NULL KEY `b`)");
630 ok(r == ERROR_BAD_QUERY_SYNTAX , "invalid query 2p return code\n");
632 r = try_query( hdb, "CREATE TABLE `a` (`` CHAR(72) NOT NULL PRIMARY KEY `b`)");
633 ok(r == ERROR_BAD_QUERY_SYNTAX , "invalid query 2p return code\n");
635 r = try_query( hdb, "CREATE TABLE `a` (`b` CHAR(72) NOT NULL PRIMARY KEY `b`)");
636 ok(r == ERROR_SUCCESS , "valid query 2z failed\n");
638 r = try_query( hdb, "CREATE TABLE `a` (`b` CHAR(72) NOT NULL PRIMARY KEY `b`)");
639 ok(r == ERROR_BAD_QUERY_SYNTAX , "created same table again\n");
641 r = try_query( hdb, "CREATE TABLE `aa` (`b` CHAR(72) NOT NULL, `c` "
642 "CHAR(72), `d` CHAR(255) NOT NULL LOCALIZABLE PRIMARY KEY `b`)");
643 ok(r == ERROR_SUCCESS , "query 4 failed\n");
645 r = MsiDatabaseCommit( hdb );
646 ok(r == ERROR_SUCCESS , "Failed to commit database after write\n");
648 r = try_query( hdb, "CREATE TABLE `blah` (`foo` CHAR(72) NOT NULL "
649 "PRIMARY KEY `foo`)");
650 ok(r == ERROR_SUCCESS , "query 4 failed\n");
652 r = try_insert_query( hdb, "insert into a ( `b` ) VALUES ( ? )");
653 ok(r == ERROR_SUCCESS , "failed to insert record in db\n");
655 r = MsiDatabaseCommit( hdb );
656 ok(r == ERROR_SUCCESS , "Failed to commit database after write\n");
658 r = try_query( hdb, "CREATE TABLE `boo` (`foo` CHAR(72) NOT NULL "
659 "PRIMARY KEY `ba`)");
660 ok(r != ERROR_SUCCESS , "query 5 succeeded\n");
662 r = try_query( hdb,"CREATE TABLE `bee` (`foo` CHAR(72) NOT NULL )");
663 ok(r != ERROR_SUCCESS , "query 6 succeeded\n");
665 r = try_query( hdb, "CREATE TABLE `temp` (`t` CHAR(72) NOT NULL "
667 ok(r == ERROR_SUCCESS , "query 7 failed\n");
669 r = try_query( hdb, "CREATE TABLE `c` (`b` CHAR NOT NULL PRIMARY KEY `b`)");
670 ok(r == ERROR_SUCCESS , "query 8 failed\n");
672 r = try_query( hdb, "select * from c");
673 ok(r == ERROR_SUCCESS , "query failed\n");
675 r = try_query( hdb, "select * from c where b = 'x");
676 ok(r == ERROR_BAD_QUERY_SYNTAX, "query failed\n");
678 r = try_query( hdb, "select * from c where b = 'x'");
679 ok(r == ERROR_SUCCESS, "query failed\n");
681 r = try_query( hdb, "select * from 'c'");
682 ok(r == ERROR_BAD_QUERY_SYNTAX, "query failed\n");
684 r = try_query( hdb, "select * from ''");
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_BAD_QUERY_SYNTAX, "query failed\n");
693 r = try_query( hdb, "select * from c where b = 'x'");
694 ok(r == ERROR_SUCCESS, "query failed\n");
696 r = try_query( hdb, "select * from c where b = '\"x'");
697 ok(r == ERROR_SUCCESS, "query failed\n");
699 if (0) /* FIXME: this query causes trouble with other tests */
701 r = try_query( hdb, "select * from c where b = '\\\'x'");
702 ok(r == ERROR_BAD_QUERY_SYNTAX, "query failed\n");
705 r = try_query( hdb, "select * from 'c'");
706 ok(r == ERROR_BAD_QUERY_SYNTAX, "query failed\n");
708 r = try_query( hdb, "CREATE TABLE `\5a` (`b` CHAR NOT NULL PRIMARY KEY `b`)" );
709 ok( r == ERROR_SUCCESS , "query failed: %u\n", r );
711 r = try_query( hdb, "SELECT * FROM \5a" );
712 ok( r == ERROR_SUCCESS , "query failed: %u\n", r );
714 r = try_query( hdb, "CREATE TABLE `a\5` (`b` CHAR NOT NULL PRIMARY KEY `b`)" );
715 ok( r == ERROR_SUCCESS , "query failed: %u\n", r );
717 r = try_query( hdb, "SELECT * FROM a\5" );
718 ok( r == ERROR_SUCCESS , "query failed: %u\n", r );
720 r = try_query( hdb, "CREATE TABLE `-a` (`b` CHAR NOT NULL PRIMARY KEY `b`)" );
721 ok( r == ERROR_SUCCESS , "query failed: %u\n", r );
723 r = try_query( hdb, "SELECT * FROM -a" );
724 todo_wine ok( r == ERROR_SUCCESS , "query failed: %u\n", r );
726 r = try_query( hdb, "CREATE TABLE `a-` (`b` CHAR NOT NULL PRIMARY KEY `b`)" );
727 ok( r == ERROR_SUCCESS , "query failed: %u\n", r );
729 r = try_query( hdb, "SELECT * FROM a-" );
730 ok( r == ERROR_SUCCESS , "query failed: %u\n", r );
732 r = MsiCloseHandle( hdb );
733 ok(r == ERROR_SUCCESS , "Failed to close database transact\n");
735 r = DeleteFile( msifile );
736 ok(r == TRUE, "file didn't exist after commit\n");
739 static void test_viewmodify(void)
741 MSIHANDLE hdb = 0, hview = 0, hrec = 0;
750 /* just MsiOpenDatabase should not create a file */
751 r = MsiOpenDatabase(msifile, MSIDBOPEN_CREATE, &hdb);
752 ok(r == ERROR_SUCCESS, "MsiOpenDatabase failed\n");
754 query = "CREATE TABLE `phone` ( "
755 "`id` INT, `name` CHAR(32), `number` CHAR(32) "
757 r = run_query( hdb, 0, query );
758 ok(r == ERROR_SUCCESS, "query failed\n");
760 query = "CREATE TABLE `_Validation` ( "
761 "`Table` CHAR(32) NOT NULL, `Column` CHAR(32) NOT NULL, "
762 "`Nullable` CHAR(4) NOT NULL, `MinValue` INT, `MaxValue` INT, "
763 "`KeyTable` CHAR(255), `KeyColumn` SHORT, `Category` CHAR(32), "
764 "`Set` CHAR(255), `Description` CHAR(255) PRIMARY KEY `Table`, `Column`)";
765 r = run_query( hdb, 0, query );
766 ok(r == ERROR_SUCCESS, "query failed\n");
768 query = "INSERT INTO `_Validation` ( `Table`, `Column`, `Nullable` ) "
769 "VALUES('phone', 'id', 'N')";
770 r = run_query( hdb, 0, query );
771 ok(r == ERROR_SUCCESS, "query failed\n");
773 /* check what the error function reports without doing anything */
775 /* passing NULL as the 3rd param make function to crash on older platforms */
776 err = MsiViewGetError( 0, NULL, &sz );
777 ok(err == MSIDBERROR_INVALIDARG, "MsiViewGetError return\n");
780 query = "SELECT * FROM `phone`";
781 r = MsiDatabaseOpenView(hdb, query, &hview);
782 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
784 /* see what happens with a good hview and bad args */
785 err = MsiViewGetError( hview, NULL, NULL );
786 ok(err == MSIDBERROR_INVALIDARG || err == MSIDBERROR_NOERROR,
787 "MsiViewGetError returns %u (expected -3)\n", err);
788 err = MsiViewGetError( hview, buffer, NULL );
789 ok(err == MSIDBERROR_INVALIDARG, "MsiViewGetError return\n");
791 /* see what happens with a zero length buffer */
794 err = MsiViewGetError( hview, buffer, &sz );
795 ok(err == MSIDBERROR_MOREDATA, "MsiViewGetError return\n");
796 ok(buffer[0] == 'x', "buffer cleared\n");
797 ok(sz == 0, "size not zero\n");
799 /* ok this one is strange */
801 err = MsiViewGetError( hview, NULL, &sz );
802 ok(err == MSIDBERROR_NOERROR, "MsiViewGetError return\n");
803 ok(sz == 0, "size not zero\n");
805 /* see if it really has an error */
808 err = MsiViewGetError( hview, buffer, &sz );
809 ok(err == MSIDBERROR_NOERROR, "MsiViewGetError return\n");
810 ok(buffer[0] == 0, "buffer not cleared\n");
811 ok(sz == 0, "size not zero\n");
813 r = MsiViewExecute(hview, 0);
814 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n");
816 /* try some invalid records */
817 r = MsiViewModify(hview, MSIMODIFY_INSERT, 0 );
818 ok(r == ERROR_INVALID_HANDLE, "MsiViewModify failed\n");
819 r = MsiViewModify(hview, -1, 0 );
820 ok(r == ERROR_INVALID_HANDLE, "MsiViewModify failed\n");
822 /* try an small record */
823 hrec = MsiCreateRecord(1);
824 r = MsiViewModify(hview, -1, hrec );
825 ok(r == ERROR_INVALID_DATA, "MsiViewModify failed\n");
829 err = MsiViewGetError( hview, buffer, &sz );
830 ok(err == MSIDBERROR_NOERROR, "MsiViewGetError return\n");
831 ok(buffer[0] == 0, "buffer not cleared\n");
832 ok(sz == 0, "size not zero\n");
834 r = MsiCloseHandle(hrec);
835 ok(r == ERROR_SUCCESS, "failed to close record\n");
837 /* insert a valid record */
838 hrec = MsiCreateRecord(3);
840 r = MsiRecordSetInteger(hrec, 1, 1);
841 ok(r == ERROR_SUCCESS, "failed to set integer\n");
842 r = MsiRecordSetString(hrec, 2, "bob");
843 ok(r == ERROR_SUCCESS, "failed to set string\n");
844 r = MsiRecordSetString(hrec, 3, "7654321");
845 ok(r == ERROR_SUCCESS, "failed to set string\n");
847 r = MsiViewExecute(hview, 0);
848 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n");
849 r = MsiViewModify(hview, MSIMODIFY_INSERT_TEMPORARY, hrec );
850 ok(r == ERROR_SUCCESS, "MsiViewModify failed\n");
853 r = MsiViewExecute(hview, 0);
854 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n");
856 r = MsiViewModify(hview, MSIMODIFY_VALIDATE_NEW, hrec );
857 ok(r == ERROR_INVALID_DATA, "MsiViewModify failed %u\n", r);
861 err = MsiViewGetError( hview, buffer, &sz );
862 ok(err == MSIDBERROR_DUPLICATEKEY, "MsiViewGetError returned %u\n", err);
863 ok(!strcmp(buffer, "id"), "expected \"id\" c, got \"%s\"\n", buffer);
864 ok(sz == 2, "size not 2\n");
866 /* insert the same thing again */
867 r = MsiViewExecute(hview, 0);
868 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n");
870 /* should fail ... */
871 r = MsiViewModify(hview, MSIMODIFY_INSERT_TEMPORARY, hrec );
872 ok(r == ERROR_FUNCTION_FAILED, "MsiViewModify failed\n");
874 r = MsiCloseHandle(hrec);
875 ok(r == ERROR_SUCCESS, "failed to close record\n");
877 r = MsiViewClose(hview);
878 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n");
879 r = MsiCloseHandle(hview);
880 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
882 query = "SELECT * FROM `phone`";
883 r = MsiDatabaseOpenView(hdb, query, &hview);
884 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
886 r = MsiViewExecute(hview, 0);
887 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n");
889 r = MsiViewFetch(hview, &hrec);
890 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n");
892 r = MsiRecordGetInteger(hrec, 1);
893 ok(r == 1, "Expected 1, got %d\n", r);
896 r = MsiRecordGetString(hrec, 2, buffer, &sz);
897 ok(r == ERROR_SUCCESS, "MsiRecordGetString failed\n");
898 ok(!lstrcmp(buffer, "bob"), "Expected bob, got %s\n", buffer);
901 r = MsiRecordGetString(hrec, 3, buffer, &sz);
902 ok(r == ERROR_SUCCESS, "MsiRecordGetString failed\n");
903 ok(!lstrcmp(buffer, "7654321"), "Expected 7654321, got %s\n", buffer);
905 /* update the view, non-primary key */
906 r = MsiRecordSetString(hrec, 3, "3141592");
907 ok(r == ERROR_SUCCESS, "MsiRecordSetString failed\n");
909 r = MsiViewModify(hview, MSIMODIFY_UPDATE, hrec);
910 ok(r == ERROR_SUCCESS, "MsiViewModify failed\n");
913 r = MsiViewModify(hview, MSIMODIFY_UPDATE, hrec);
914 ok(r == ERROR_SUCCESS, "MsiViewModify failed: %d\n", r);
916 /* update the view, primary key */
917 r = MsiRecordSetInteger(hrec, 1, 5);
918 ok(r == ERROR_SUCCESS, "MsiRecordSetInteger failed\n");
920 r = MsiViewModify(hview, MSIMODIFY_UPDATE, hrec);
921 ok(r == ERROR_FUNCTION_FAILED, "MsiViewModify failed\n");
923 r = MsiCloseHandle(hrec);
924 ok(r == ERROR_SUCCESS, "failed to close record\n");
926 r = MsiViewClose(hview);
927 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n");
928 r = MsiCloseHandle(hview);
929 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
931 query = "SELECT * FROM `phone`";
932 r = MsiDatabaseOpenView(hdb, query, &hview);
933 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
935 r = MsiViewExecute(hview, 0);
936 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n");
938 r = MsiViewFetch(hview, &hrec);
939 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n");
941 r = MsiRecordGetInteger(hrec, 1);
942 ok(r == 1, "Expected 1, got %d\n", r);
945 r = MsiRecordGetString(hrec, 2, buffer, &sz);
946 ok(r == ERROR_SUCCESS, "MsiRecordGetString failed\n");
947 ok(!lstrcmp(buffer, "bob"), "Expected bob, got %s\n", buffer);
950 r = MsiRecordGetString(hrec, 3, buffer, &sz);
951 ok(r == ERROR_SUCCESS, "MsiRecordGetString failed\n");
952 ok(!lstrcmp(buffer, "3141592"), "Expected 3141592, got %s\n", buffer);
954 r = MsiCloseHandle(hrec);
955 ok(r == ERROR_SUCCESS, "failed to close record\n");
957 /* use a record that doesn't come from a view fetch */
958 hrec = MsiCreateRecord(3);
959 ok(hrec != 0, "MsiCreateRecord failed\n");
961 r = MsiRecordSetInteger(hrec, 1, 3);
962 ok(r == ERROR_SUCCESS, "failed to set integer\n");
963 r = MsiRecordSetString(hrec, 2, "jane");
964 ok(r == ERROR_SUCCESS, "failed to set string\n");
965 r = MsiRecordSetString(hrec, 3, "112358");
966 ok(r == ERROR_SUCCESS, "failed to set string\n");
968 r = MsiViewModify(hview, MSIMODIFY_UPDATE, hrec);
969 ok(r == ERROR_FUNCTION_FAILED, "Expected ERROR_FUNCTION_FAILED, got %d\n", r);
971 r = MsiCloseHandle(hrec);
972 ok(r == ERROR_SUCCESS, "failed to close record\n");
974 /* use a record that doesn't come from a view fetch, primary key matches */
975 hrec = MsiCreateRecord(3);
976 ok(hrec != 0, "MsiCreateRecord failed\n");
978 r = MsiRecordSetInteger(hrec, 1, 1);
979 ok(r == ERROR_SUCCESS, "failed to set integer\n");
980 r = MsiRecordSetString(hrec, 2, "jane");
981 ok(r == ERROR_SUCCESS, "failed to set string\n");
982 r = MsiRecordSetString(hrec, 3, "112358");
983 ok(r == ERROR_SUCCESS, "failed to set string\n");
985 r = MsiViewModify(hview, MSIMODIFY_UPDATE, hrec);
986 ok(r == ERROR_FUNCTION_FAILED, "MsiViewModify failed\n");
988 r = MsiCloseHandle(hrec);
989 ok(r == ERROR_SUCCESS, "failed to close record\n");
991 hrec = MsiCreateRecord(3);
993 r = MsiRecordSetInteger(hrec, 1, 2);
994 ok(r == ERROR_SUCCESS, "failed to set integer\n");
995 r = MsiRecordSetString(hrec, 2, "nick");
996 ok(r == ERROR_SUCCESS, "failed to set string\n");
997 r = MsiRecordSetString(hrec, 3, "141421");
998 ok(r == ERROR_SUCCESS, "failed to set string\n");
1000 r = MsiViewExecute(hview, 0);
1001 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n");
1002 r = MsiViewModify(hview, MSIMODIFY_INSERT_TEMPORARY, hrec );
1003 ok(r == ERROR_SUCCESS, "MsiViewModify failed\n");
1005 r = MsiCloseHandle(hrec);
1006 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
1007 r = MsiViewClose(hview);
1008 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n");
1009 r = MsiCloseHandle(hview);
1010 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
1012 query = "SELECT * FROM `phone` WHERE `id` = 1";
1013 r = MsiDatabaseOpenView(hdb, query, &hview);
1014 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
1015 r = MsiViewExecute(hview, 0);
1016 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n");
1017 r = MsiViewFetch(hview, &hrec);
1018 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n");
1020 /* change the id to match the second row */
1021 r = MsiRecordSetInteger(hrec, 1, 2);
1022 ok(r == ERROR_SUCCESS, "failed to set integer\n");
1023 r = MsiRecordSetString(hrec, 2, "jerry");
1024 ok(r == ERROR_SUCCESS, "failed to set string\n");
1026 r = MsiViewModify(hview, MSIMODIFY_UPDATE, hrec);
1027 ok(r == ERROR_FUNCTION_FAILED, "MsiViewModify failed\n");
1029 r = MsiCloseHandle(hrec);
1030 ok(r == ERROR_SUCCESS, "failed to close record\n");
1031 r = MsiViewClose(hview);
1032 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n");
1033 r = MsiCloseHandle(hview);
1034 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
1036 /* broader search */
1037 query = "SELECT * FROM `phone` ORDER BY `id`";
1038 r = MsiDatabaseOpenView(hdb, query, &hview);
1039 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
1040 r = MsiViewExecute(hview, 0);
1041 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n");
1042 r = MsiViewFetch(hview, &hrec);
1043 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n");
1045 /* change the id to match the second row */
1046 r = MsiRecordSetInteger(hrec, 1, 2);
1047 ok(r == ERROR_SUCCESS, "failed to set integer\n");
1048 r = MsiRecordSetString(hrec, 2, "jerry");
1049 ok(r == ERROR_SUCCESS, "failed to set string\n");
1051 r = MsiViewModify(hview, MSIMODIFY_UPDATE, hrec);
1052 ok(r == ERROR_FUNCTION_FAILED, "MsiViewModify failed\n");
1054 r = MsiCloseHandle(hrec);
1055 ok(r == ERROR_SUCCESS, "failed to close record\n");
1056 r = MsiViewClose(hview);
1057 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n");
1058 r = MsiCloseHandle(hview);
1059 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
1061 r = MsiCloseHandle( hdb );
1062 ok(r == ERROR_SUCCESS, "MsiOpenDatabase close failed\n");
1065 static MSIHANDLE create_db(void)
1070 DeleteFile(msifile);
1072 /* create an empty database */
1073 res = MsiOpenDatabase(msifile, MSIDBOPEN_CREATE, &hdb );
1074 ok( res == ERROR_SUCCESS , "Failed to create database\n" );
1075 if( res != ERROR_SUCCESS )
1078 res = MsiDatabaseCommit( hdb );
1079 ok( res == ERROR_SUCCESS , "Failed to commit database\n" );
1084 static void test_getcolinfo(void)
1086 MSIHANDLE hdb, hview = 0, rec = 0;
1091 /* create an empty db */
1093 ok( hdb, "failed to create db\n");
1095 /* tables should be present */
1096 r = MsiDatabaseOpenView(hdb, "select * from _Tables", &hview);
1097 ok( r == ERROR_SUCCESS, "failed to open query\n");
1099 r = MsiViewExecute(hview, 0);
1100 ok( r == ERROR_SUCCESS, "failed to execute query\n");
1102 /* check that NAMES works */
1104 r = MsiViewGetColumnInfo( hview, MSICOLINFO_NAMES, &rec );
1105 ok( r == ERROR_SUCCESS, "failed to get names\n");
1107 r = MsiRecordGetString(rec, 1, buffer, &sz );
1108 ok( r == ERROR_SUCCESS, "failed to get string\n");
1109 ok( !strcmp(buffer,"Name"), "_Tables has wrong column name\n");
1110 r = MsiCloseHandle( rec );
1111 ok( r == ERROR_SUCCESS, "failed to close record handle\n");
1113 /* check that TYPES works */
1115 r = MsiViewGetColumnInfo( hview, MSICOLINFO_TYPES, &rec );
1116 ok( r == ERROR_SUCCESS, "failed to get names\n");
1118 r = MsiRecordGetString(rec, 1, buffer, &sz );
1119 ok( r == ERROR_SUCCESS, "failed to get string\n");
1120 ok( !strcmp(buffer,"s64"), "_Tables has wrong column type\n");
1121 r = MsiCloseHandle( rec );
1122 ok( r == ERROR_SUCCESS, "failed to close record handle\n");
1124 /* check that invalid values fail */
1126 r = MsiViewGetColumnInfo( hview, 100, &rec );
1127 ok( r == ERROR_INVALID_PARAMETER, "wrong error code\n");
1128 ok( rec == 0, "returned a record\n");
1130 r = MsiViewGetColumnInfo( hview, MSICOLINFO_TYPES, NULL );
1131 ok( r == ERROR_INVALID_PARAMETER, "wrong error code\n");
1133 r = MsiViewGetColumnInfo( 0, MSICOLINFO_TYPES, &rec );
1134 ok( r == ERROR_INVALID_HANDLE, "wrong error code\n");
1136 r = MsiViewClose(hview);
1137 ok( r == ERROR_SUCCESS, "failed to close view\n");
1138 r = MsiCloseHandle(hview);
1139 ok( r == ERROR_SUCCESS, "failed to close view handle\n");
1140 r = MsiCloseHandle(hdb);
1141 ok( r == ERROR_SUCCESS, "failed to close database\n");
1144 static MSIHANDLE get_column_info(MSIHANDLE hdb, const char *query, MSICOLINFO type)
1146 MSIHANDLE hview = 0, rec = 0;
1149 r = MsiDatabaseOpenView(hdb, query, &hview);
1150 if( r != ERROR_SUCCESS )
1153 r = MsiViewExecute(hview, 0);
1154 if( r == ERROR_SUCCESS )
1156 MsiViewGetColumnInfo( hview, type, &rec );
1158 MsiViewClose(hview);
1159 MsiCloseHandle(hview);
1163 static UINT get_columns_table_type(MSIHANDLE hdb, const char *table, UINT field)
1165 MSIHANDLE hview = 0, rec = 0;
1169 sprintf(query, "select * from `_Columns` where `Table` = '%s'", table );
1171 r = MsiDatabaseOpenView(hdb, query, &hview);
1172 if( r != ERROR_SUCCESS )
1175 r = MsiViewExecute(hview, 0);
1176 if( r == ERROR_SUCCESS )
1180 r = MsiViewFetch( hview, &rec );
1181 if( r != ERROR_SUCCESS)
1183 r = MsiRecordGetInteger( rec, 2 );
1185 type = MsiRecordGetInteger( rec, 4 );
1186 MsiCloseHandle( rec );
1189 MsiViewClose(hview);
1190 MsiCloseHandle(hview);
1194 static BOOL check_record( MSIHANDLE rec, UINT field, LPCSTR val )
1201 r = MsiRecordGetString( rec, field, buffer, &sz );
1202 return (r == ERROR_SUCCESS ) && !strcmp(val, buffer);
1205 static void test_viewgetcolumninfo(void)
1207 MSIHANDLE hdb = 0, rec;
1211 ok( hdb, "failed to create db\n");
1213 r = run_query( hdb, 0,
1214 "CREATE TABLE `Properties` "
1215 "( `Property` CHAR(255), "
1216 " `Value` CHAR(1), "
1218 " `Integervalue` INTEGER, "
1219 " `Shortvalue` SHORT, "
1220 " `Longvalue` LONG, "
1221 " `Longcharvalue` LONGCHAR "
1222 " PRIMARY KEY `Property`)" );
1223 ok( r == ERROR_SUCCESS , "Failed to create table\n" );
1225 /* check the column types */
1226 rec = get_column_info( hdb, "select * from `Properties`", MSICOLINFO_TYPES );
1227 ok( rec, "failed to get column info record\n" );
1229 ok( check_record( rec, 1, "S255"), "wrong record type\n");
1230 ok( check_record( rec, 2, "S1"), "wrong record type\n");
1231 ok( check_record( rec, 3, "I2"), "wrong record type\n");
1232 ok( check_record( rec, 4, "I2"), "wrong record type\n");
1233 ok( check_record( rec, 5, "I2"), "wrong record type\n");
1234 ok( check_record( rec, 6, "I4"), "wrong record type\n");
1235 ok( check_record( rec, 7, "S0"), "wrong record type\n");
1237 MsiCloseHandle( rec );
1239 /* check the type in _Columns */
1240 ok( 0x3dff == get_columns_table_type(hdb, "Properties", 1 ), "_columns table wrong\n");
1241 ok( 0x1d01 == get_columns_table_type(hdb, "Properties", 2 ), "_columns table wrong\n");
1242 ok( 0x1502 == get_columns_table_type(hdb, "Properties", 3 ), "_columns table wrong\n");
1243 ok( 0x1502 == get_columns_table_type(hdb, "Properties", 4 ), "_columns table wrong\n");
1244 ok( 0x1502 == get_columns_table_type(hdb, "Properties", 5 ), "_columns table wrong\n");
1245 ok( 0x1104 == get_columns_table_type(hdb, "Properties", 6 ), "_columns table wrong\n");
1246 ok( 0x1d00 == get_columns_table_type(hdb, "Properties", 7 ), "_columns table wrong\n");
1248 /* now try the names */
1249 rec = get_column_info( hdb, "select * from `Properties`", MSICOLINFO_NAMES );
1250 ok( rec, "failed to get column info record\n" );
1252 ok( check_record( rec, 1, "Property"), "wrong record type\n");
1253 ok( check_record( rec, 2, "Value"), "wrong record type\n");
1254 ok( check_record( rec, 3, "Intvalue"), "wrong record type\n");
1255 ok( check_record( rec, 4, "Integervalue"), "wrong record type\n");
1256 ok( check_record( rec, 5, "Shortvalue"), "wrong record type\n");
1257 ok( check_record( rec, 6, "Longvalue"), "wrong record type\n");
1258 ok( check_record( rec, 7, "Longcharvalue"), "wrong record type\n");
1260 MsiCloseHandle( rec );
1262 r = run_query( hdb, 0,
1263 "CREATE TABLE `Binary` "
1264 "( `Name` CHAR(255), `Data` OBJECT PRIMARY KEY `Name`)" );
1265 ok( r == ERROR_SUCCESS , "Failed to create table\n" );
1267 /* check the column types */
1268 rec = get_column_info( hdb, "select * from `Binary`", MSICOLINFO_TYPES );
1269 ok( rec, "failed to get column info record\n" );
1271 ok( check_record( rec, 1, "S255"), "wrong record type\n");
1272 ok( check_record( rec, 2, "V0"), "wrong record type\n");
1274 MsiCloseHandle( rec );
1276 /* check the type in _Columns */
1277 ok( 0x3dff == get_columns_table_type(hdb, "Binary", 1 ), "_columns table wrong\n");
1278 ok( 0x1900 == get_columns_table_type(hdb, "Binary", 2 ), "_columns table wrong\n");
1280 /* now try the names */
1281 rec = get_column_info( hdb, "select * from `Binary`", MSICOLINFO_NAMES );
1282 ok( rec, "failed to get column info record\n" );
1284 ok( check_record( rec, 1, "Name"), "wrong record type\n");
1285 ok( check_record( rec, 2, "Data"), "wrong record type\n");
1286 MsiCloseHandle( rec );
1288 r = run_query( hdb, 0,
1289 "CREATE TABLE `UIText` "
1290 "( `Key` CHAR(72) NOT NULL, `Text` CHAR(255) LOCALIZABLE PRIMARY KEY `Key`)" );
1291 ok( r == ERROR_SUCCESS , "Failed to create table\n" );
1293 ok( 0x2d48 == get_columns_table_type(hdb, "UIText", 1 ), "_columns table wrong\n");
1294 ok( 0x1fff == get_columns_table_type(hdb, "UIText", 2 ), "_columns table wrong\n");
1296 rec = get_column_info( hdb, "select * from `UIText`", MSICOLINFO_NAMES );
1297 ok( rec, "failed to get column info record\n" );
1298 ok( check_record( rec, 1, "Key"), "wrong record type\n");
1299 ok( check_record( rec, 2, "Text"), "wrong record type\n");
1300 MsiCloseHandle( rec );
1302 rec = get_column_info( hdb, "select * from `UIText`", MSICOLINFO_TYPES );
1303 ok( rec, "failed to get column info record\n" );
1304 ok( check_record( rec, 1, "s72"), "wrong record type\n");
1305 ok( check_record( rec, 2, "L255"), "wrong record type\n");
1306 MsiCloseHandle( rec );
1308 MsiCloseHandle( hdb );
1311 static void test_msiexport(void)
1313 MSIHANDLE hdb = 0, hview = 0;
1316 char path[MAX_PATH];
1317 const char file[] = "phone.txt";
1321 const char expected[] =
1322 "id\tname\tnumber\r\n"
1325 "1\tAbe\t8675309\r\n";
1327 DeleteFile(msifile);
1329 /* just MsiOpenDatabase should not create a file */
1330 r = MsiOpenDatabase(msifile, MSIDBOPEN_CREATE, &hdb);
1331 ok(r == ERROR_SUCCESS, "MsiOpenDatabase failed\n");
1333 /* create a table */
1334 query = "CREATE TABLE `phone` ( "
1335 "`id` INT, `name` CHAR(32), `number` CHAR(32) "
1336 "PRIMARY KEY `id`)";
1337 r = MsiDatabaseOpenView(hdb, query, &hview);
1338 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
1339 r = MsiViewExecute(hview, 0);
1340 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n");
1341 r = MsiViewClose(hview);
1342 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n");
1343 r = MsiCloseHandle(hview);
1344 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
1346 /* insert a value into it */
1347 query = "INSERT INTO `phone` ( `id`, `name`, `number` )"
1348 "VALUES('1', 'Abe', '8675309')";
1349 r = MsiDatabaseOpenView(hdb, query, &hview);
1350 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
1351 r = MsiViewExecute(hview, 0);
1352 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n");
1353 r = MsiViewClose(hview);
1354 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n");
1355 r = MsiCloseHandle(hview);
1356 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
1358 GetCurrentDirectory(MAX_PATH, path);
1360 r = MsiDatabaseExport(hdb, "phone", path, file);
1361 ok(r == ERROR_SUCCESS, "MsiDatabaseExport failed\n");
1363 MsiCloseHandle(hdb);
1365 lstrcat(path, "\\");
1366 lstrcat(path, file);
1368 /* check the data that was written */
1370 memset(buffer, 0, sizeof buffer);
1371 handle = CreateFile(path, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
1372 if (handle != INVALID_HANDLE_VALUE)
1374 ReadFile(handle, buffer, sizeof buffer, &length, NULL);
1375 CloseHandle(handle);
1379 ok(0, "failed to open file %s\n", path);
1381 ok( length == strlen(expected), "length of data wrong\n");
1382 ok( !lstrcmp(buffer, expected), "data doesn't match\n");
1383 DeleteFile(msifile);
1386 static void test_longstrings(void)
1388 const char insert_query[] =
1389 "INSERT INTO `strings` ( `id`, `val` ) VALUES('1', 'Z')";
1391 MSIHANDLE hdb = 0, hview = 0, hrec = 0;
1394 const DWORD STRING_LENGTH = 0x10005;
1396 DeleteFile(msifile);
1397 /* just MsiOpenDatabase should not create a file */
1398 r = MsiOpenDatabase(msifile, MSIDBOPEN_CREATE, &hdb);
1399 ok(r == ERROR_SUCCESS, "MsiOpenDatabase failed\n");
1401 /* create a table */
1403 "CREATE TABLE `strings` ( `id` INT, `val` CHAR(0) PRIMARY KEY `id`)");
1404 ok(r == ERROR_SUCCESS, "query failed\n");
1406 /* try a insert a very long string */
1407 str = HeapAlloc(GetProcessHeap(), 0, STRING_LENGTH+sizeof insert_query);
1408 len = strchr(insert_query, 'Z') - insert_query;
1409 strcpy(str, insert_query);
1410 memset(str+len, 'Z', STRING_LENGTH);
1411 strcpy(str+len+STRING_LENGTH, insert_query+len+1);
1412 r = try_query( hdb, str );
1413 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
1415 HeapFree(GetProcessHeap(), 0, str);
1417 MsiDatabaseCommit(hdb);
1418 ok(r == ERROR_SUCCESS, "MsiDatabaseCommit failed\n");
1419 MsiCloseHandle(hdb);
1421 r = MsiOpenDatabase(msifile, MSIDBOPEN_READONLY, &hdb);
1422 ok(r == ERROR_SUCCESS, "MsiOpenDatabase failed\n");
1424 r = MsiDatabaseOpenView(hdb, "select * from `strings` where `id` = 1", &hview);
1425 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
1427 r = MsiViewExecute(hview, 0);
1428 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n");
1430 r = MsiViewFetch(hview, &hrec);
1431 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n");
1433 MsiViewClose(hview);
1434 MsiCloseHandle(hview);
1436 r = MsiRecordGetString(hrec, 2, NULL, &len);
1437 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n");
1438 ok(len == STRING_LENGTH, "string length wrong\n");
1440 MsiCloseHandle(hrec);
1441 MsiCloseHandle(hdb);
1442 DeleteFile(msifile);
1445 static void create_file_data(LPCSTR name, LPCSTR data, DWORD size)
1450 file = CreateFileA(name, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
1451 if (file == INVALID_HANDLE_VALUE)
1454 WriteFile(file, data, strlen(data), &written, NULL);
1455 WriteFile(file, "\n", strlen("\n"), &written, NULL);
1459 SetFilePointer(file, size, NULL, FILE_BEGIN);
1466 #define create_file(name) create_file_data(name, name, 0)
1468 static void test_streamtable(void)
1470 MSIHANDLE hdb = 0, rec, view, hsi;
1471 char file[MAX_PATH];
1477 ok( hdb, "failed to create db\n");
1479 r = run_query( hdb, 0,
1480 "CREATE TABLE `Properties` "
1481 "( `Property` CHAR(255), `Value` CHAR(1) PRIMARY KEY `Property`)" );
1482 ok( r == ERROR_SUCCESS , "Failed to create table\n" );
1484 r = run_query( hdb, 0,
1485 "INSERT INTO `Properties` "
1486 "( `Value`, `Property` ) VALUES ( 'Prop', 'value' )" );
1487 ok( r == ERROR_SUCCESS, "Failed to add to table\n" );
1489 r = MsiDatabaseCommit( hdb );
1490 ok( r == ERROR_SUCCESS , "Failed to commit database\n" );
1492 MsiCloseHandle( hdb );
1494 r = MsiOpenDatabase(msifile, MSIDBOPEN_TRANSACT, &hdb );
1495 ok( r == ERROR_SUCCESS , "Failed to open database\n" );
1497 /* check the column types */
1498 rec = get_column_info( hdb, "select * from `_Streams`", MSICOLINFO_TYPES );
1499 ok( rec, "failed to get column info record\n" );
1501 ok( check_record( rec, 1, "s62"), "wrong record type\n");
1502 ok( check_record( rec, 2, "V0"), "wrong record type\n");
1504 MsiCloseHandle( rec );
1506 /* now try the names */
1507 rec = get_column_info( hdb, "select * from `_Streams`", MSICOLINFO_NAMES );
1508 ok( rec, "failed to get column info record\n" );
1510 ok( check_record( rec, 1, "Name"), "wrong record type\n");
1511 ok( check_record( rec, 2, "Data"), "wrong record type\n");
1513 MsiCloseHandle( rec );
1515 r = MsiDatabaseOpenView( hdb,
1516 "SELECT * FROM `_Streams` WHERE `Name` = '\5SummaryInformation'", &view );
1517 ok( r == ERROR_SUCCESS, "Failed to open database view: %u\n", r );
1519 r = MsiViewExecute( view, 0 );
1520 ok( r == ERROR_SUCCESS, "Failed to execute view: %u\n", r );
1522 r = MsiViewFetch( view, &rec );
1523 ok( r == ERROR_NO_MORE_ITEMS, "Unexpected result: %u\n", r );
1525 MsiCloseHandle( rec );
1526 MsiViewClose( view );
1527 MsiCloseHandle( view );
1529 /* create a summary information stream */
1530 r = MsiGetSummaryInformationA( hdb, NULL, 1, &hsi );
1531 ok( r == ERROR_SUCCESS, "Failed to get summary information handle: %u\n", r );
1533 r = MsiSummaryInfoSetPropertyA( hsi, PID_SECURITY, VT_I4, 2, NULL, NULL );
1534 ok( r == ERROR_SUCCESS, "Failed to set property: %u\n", r );
1536 r = MsiSummaryInfoPersist( hsi );
1537 ok( r == ERROR_SUCCESS, "Failed to save summary information: %u\n", r );
1539 MsiCloseHandle( hsi );
1541 r = MsiDatabaseOpenView( hdb,
1542 "SELECT * FROM `_Streams` WHERE `Name` = '\5SummaryInformation'", &view );
1543 ok( r == ERROR_SUCCESS, "Failed to open database view: %u\n", r );
1545 r = MsiViewExecute( view, 0 );
1546 ok( r == ERROR_SUCCESS, "Failed to execute view: %u\n", r );
1548 r = MsiViewFetch( view, &rec );
1549 ok( r == ERROR_SUCCESS, "Unexpected result: %u\n", r );
1551 MsiCloseHandle( rec );
1552 MsiViewClose( view );
1553 MsiCloseHandle( view );
1555 /* insert a file into the _Streams table */
1556 create_file( "test.txt" );
1558 rec = MsiCreateRecord( 2 );
1559 MsiRecordSetString( rec, 1, "data" );
1561 r = MsiRecordSetStream( rec, 2, "test.txt" );
1562 ok( r == ERROR_SUCCESS, "Failed to add stream data to the record: %d\n", r);
1564 DeleteFile("test.txt");
1566 r = MsiDatabaseOpenView( hdb,
1567 "INSERT INTO `_Streams` ( `Name`, `Data` ) VALUES ( ?, ? )", &view );
1568 ok( r == ERROR_SUCCESS, "Failed to open database view: %d\n", r);
1570 r = MsiViewExecute( view, rec );
1571 ok( r == ERROR_SUCCESS, "Failed to execute view: %d\n", r);
1573 MsiCloseHandle( rec );
1574 MsiViewClose( view );
1575 MsiCloseHandle( view );
1577 /* insert another one */
1578 create_file( "test1.txt" );
1580 rec = MsiCreateRecord( 2 );
1581 MsiRecordSetString( rec, 1, "data1" );
1583 r = MsiRecordSetStream( rec, 2, "test1.txt" );
1584 ok( r == ERROR_SUCCESS, "Failed to add stream data to the record: %d\n", r);
1586 DeleteFile("test1.txt");
1588 r = MsiDatabaseOpenView( hdb,
1589 "INSERT INTO `_Streams` ( `Name`, `Data` ) VALUES ( ?, ? )", &view );
1590 ok( r == ERROR_SUCCESS, "Failed to open database view: %d\n", r);
1592 r = MsiViewExecute( view, rec );
1593 ok( r == ERROR_SUCCESS, "Failed to execute view: %d\n", r);
1595 MsiCloseHandle( rec );
1596 MsiViewClose( view );
1597 MsiCloseHandle( view );
1599 r = MsiDatabaseOpenView( hdb,
1600 "SELECT `Name`, `Data` FROM `_Streams` WHERE `Name` = 'data'", &view );
1601 ok( r == ERROR_SUCCESS, "Failed to open database view: %d\n", r);
1603 r = MsiViewExecute( view, 0 );
1604 ok( r == ERROR_SUCCESS, "Failed to execute view: %d\n", r);
1606 r = MsiViewFetch( view, &rec );
1607 ok( r == ERROR_SUCCESS, "Failed to fetch record: %d\n", r);
1610 r = MsiRecordGetString( rec, 1, file, &size );
1611 ok( r == ERROR_SUCCESS, "Failed to get string: %d\n", r);
1612 ok( !lstrcmp(file, "data"), "Expected 'data', got %s\n", file);
1615 memset(buf, 0, MAX_PATH);
1616 r = MsiRecordReadStream( rec, 2, buf, &size );
1617 ok( r == ERROR_SUCCESS, "Failed to get stream: %d\n", r);
1618 ok( !lstrcmp(buf, "test.txt\n"), "Expected 'test.txt\\n', got %s\n", buf);
1620 MsiCloseHandle( rec );
1621 MsiViewClose( view );
1622 MsiCloseHandle( view );
1624 r = MsiDatabaseOpenView( hdb,
1625 "SELECT `Name`, `Data` FROM `_Streams` WHERE `Name` = 'data1'", &view );
1626 ok( r == ERROR_SUCCESS, "Failed to open database view: %d\n", r);
1628 r = MsiViewExecute( view, 0 );
1629 ok( r == ERROR_SUCCESS, "Failed to execute view: %d\n", r);
1631 r = MsiViewFetch( view, &rec );
1632 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1635 r = MsiRecordGetString( rec, 1, file, &size );
1636 ok( r == ERROR_SUCCESS, "Failed to get string: %d\n", r);
1637 ok( !lstrcmp(file, "data1"), "Expected 'data1', got %s\n", file);
1640 memset(buf, 0, MAX_PATH);
1641 r = MsiRecordReadStream( rec, 2, buf, &size );
1642 ok( r == ERROR_SUCCESS, "Failed to get stream: %d\n", r);
1643 ok( !lstrcmp(buf, "test1.txt\n"), "Expected 'test1.txt\\n', got %s\n", buf);
1645 MsiCloseHandle( rec );
1646 MsiViewClose( view );
1647 MsiCloseHandle( view );
1649 /* perform an update */
1650 create_file( "test2.txt" );
1651 rec = MsiCreateRecord( 1 );
1653 r = MsiRecordSetStream( rec, 1, "test2.txt" );
1654 ok( r == ERROR_SUCCESS, "Failed to add stream data to the record: %d\n", r);
1656 DeleteFile("test2.txt");
1658 r = MsiDatabaseOpenView( hdb,
1659 "UPDATE `_Streams` SET `Data` = ? WHERE `Name` = 'data1'", &view );
1660 ok( r == ERROR_SUCCESS, "Failed to open database view: %d\n", r);
1662 r = MsiViewExecute( view, rec );
1663 ok( r == ERROR_SUCCESS, "Failed to execute view: %d\n", r);
1665 MsiCloseHandle( rec );
1666 MsiViewClose( view );
1667 MsiCloseHandle( view );
1669 r = MsiDatabaseOpenView( hdb,
1670 "SELECT `Name`, `Data` FROM `_Streams` WHERE `Name` = 'data1'", &view );
1671 ok( r == ERROR_SUCCESS, "Failed to open database view: %d\n", r);
1673 r = MsiViewExecute( view, 0 );
1674 ok( r == ERROR_SUCCESS, "Failed to execute view: %d\n", r);
1676 r = MsiViewFetch( view, &rec );
1677 ok( r == ERROR_SUCCESS, "Failed to fetch record: %d\n", r);
1680 r = MsiRecordGetString( rec, 1, file, &size );
1681 ok( r == ERROR_SUCCESS, "Failed to get string: %d\n", r);
1682 ok( !lstrcmp(file, "data1"), "Expected 'data1', got %s\n", file);
1685 memset(buf, 0, MAX_PATH);
1686 r = MsiRecordReadStream( rec, 2, buf, &size );
1687 ok( r == ERROR_SUCCESS, "Failed to get stream: %d\n", r);
1688 todo_wine ok( !lstrcmp(buf, "test2.txt\n"), "Expected 'test2.txt\\n', got %s\n", buf);
1690 MsiCloseHandle( rec );
1691 MsiViewClose( view );
1692 MsiCloseHandle( view );
1693 MsiCloseHandle( hdb );
1694 DeleteFile(msifile);
1697 static void test_binary(void)
1699 MSIHANDLE hdb = 0, rec;
1700 char file[MAX_PATH];
1706 /* insert a file into the Binary table */
1707 r = MsiOpenDatabase(msifile, MSIDBOPEN_CREATE, &hdb );
1708 ok( r == ERROR_SUCCESS , "Failed to open database\n" );
1710 query = "CREATE TABLE `Binary` ( `Name` CHAR(72) NOT NULL, `ID` INT NOT NULL, `Data` OBJECT PRIMARY KEY `Name`, `ID`)";
1711 r = run_query( hdb, 0, query );
1712 ok( r == ERROR_SUCCESS, "Cannot create Binary table: %d\n", r );
1714 create_file( "test.txt" );
1715 rec = MsiCreateRecord( 1 );
1716 r = MsiRecordSetStream( rec, 1, "test.txt" );
1717 ok( r == ERROR_SUCCESS, "Failed to add stream data to the record: %d\n", r);
1718 DeleteFile( "test.txt" );
1720 query = "INSERT INTO `Binary` ( `Name`, `ID`, `Data` ) VALUES ( 'filename1', 1, ? )";
1721 r = run_query( hdb, rec, query );
1722 ok( r == ERROR_SUCCESS, "Insert into Binary table failed: %d\n", r );
1724 r = MsiCloseHandle( rec );
1725 ok( r == ERROR_SUCCESS , "Failed to close record handle\n" );
1727 r = MsiDatabaseCommit( hdb );
1728 ok( r == ERROR_SUCCESS , "Failed to commit database\n" );
1730 r = MsiCloseHandle( hdb );
1731 ok( r == ERROR_SUCCESS , "Failed to close database\n" );
1733 /* read file from the Stream table */
1734 r = MsiOpenDatabase( msifile, MSIDBOPEN_READONLY, &hdb );
1735 ok( r == ERROR_SUCCESS , "Failed to open database\n" );
1737 query = "SELECT * FROM `_Streams`";
1738 r = do_query( hdb, query, &rec );
1739 ok( r == ERROR_SUCCESS, "SELECT query failed: %d\n", r );
1742 r = MsiRecordGetString( rec, 1, file, &size );
1743 ok( r == ERROR_SUCCESS, "Failed to get string: %d\n", r );
1744 ok( !lstrcmp(file, "Binary.filename1.1"), "Expected 'Binary.filename1.1', got %s\n", file );
1747 memset( buf, 0, MAX_PATH );
1748 r = MsiRecordReadStream( rec, 2, buf, &size );
1749 ok( r == ERROR_SUCCESS, "Failed to get stream: %d\n", r );
1750 ok( !lstrcmp(buf, "test.txt\n"), "Expected 'test.txt\\n', got %s\n", buf );
1752 r = MsiCloseHandle( rec );
1753 ok( r == ERROR_SUCCESS , "Failed to close record handle\n" );
1755 /* read file from the Binary table */
1756 query = "SELECT * FROM `Binary`";
1757 r = do_query( hdb, query, &rec );
1758 ok( r == ERROR_SUCCESS, "SELECT query failed: %d\n", r );
1761 r = MsiRecordGetString( rec, 1, file, &size );
1762 ok( r == ERROR_SUCCESS, "Failed to get string: %d\n", r );
1763 ok( !lstrcmp(file, "filename1"), "Expected 'filename1', got %s\n", file );
1766 memset( buf, 0, MAX_PATH );
1767 r = MsiRecordReadStream( rec, 3, buf, &size );
1768 ok( r == ERROR_SUCCESS, "Failed to get stream: %d\n", r );
1769 ok( !lstrcmp(buf, "test.txt\n"), "Expected 'test.txt\\n', got %s\n", buf );
1771 r = MsiCloseHandle( rec );
1772 ok( r == ERROR_SUCCESS , "Failed to close record handle\n" );
1774 r = MsiCloseHandle( hdb );
1775 ok( r == ERROR_SUCCESS , "Failed to close database\n" );
1777 DeleteFile( msifile );
1780 static void test_where_not_in_selected(void)
1782 MSIHANDLE hdb = 0, rec, view;
1787 ok( hdb, "failed to create db\n");
1789 r = run_query(hdb, 0,
1790 "CREATE TABLE `IESTable` ("
1791 "`Action` CHAR(64), "
1792 "`Condition` CHAR(64), "
1793 "`Sequence` LONG PRIMARY KEY `Sequence`)");
1794 ok( r == S_OK, "Cannot create IESTable table: %d\n", r);
1796 r = run_query(hdb, 0,
1797 "CREATE TABLE `CATable` ("
1798 "`Action` CHAR(64), "
1799 "`Type` LONG PRIMARY KEY `Type`)");
1800 ok( r == S_OK, "Cannot create CATable table: %d\n", r);
1802 r = run_query(hdb, 0, "INSERT INTO `IESTable` "
1803 "( `Action`, `Condition`, `Sequence`) "
1804 "VALUES ( 'clean', 'cond4', 4)");
1805 ok( r == S_OK, "cannot add entry to IESTable table:%d\n", r );
1807 r = run_query(hdb, 0, "INSERT INTO `IESTable` "
1808 "( `Action`, `Condition`, `Sequence`) "
1809 "VALUES ( 'depends', 'cond1', 1)");
1810 ok( r == S_OK, "cannot add entry to IESTable table:%d\n", r );
1812 r = run_query(hdb, 0, "INSERT INTO `IESTable` "
1813 "( `Action`, `Condition`, `Sequence`) "
1814 "VALUES ( 'build', 'cond2', 2)");
1815 ok( r == S_OK, "cannot add entry to IESTable table:%d\n", r );
1817 r = run_query(hdb, 0, "INSERT INTO `IESTable` "
1818 "( `Action`, `Condition`, `Sequence`) "
1819 "VALUES ( 'build2', 'cond6', 6)");
1820 ok( r == S_OK, "cannot add entry to IESTable table:%d\n", r );
1822 r = run_query(hdb, 0, "INSERT INTO `IESTable` "
1823 "( `Action`, `Condition`, `Sequence`) "
1824 "VALUES ( 'build', 'cond3', 3)");
1825 ok(r == S_OK, "cannot add entry to IESTable table:%d\n", r );
1827 r = run_query(hdb, 0, "INSERT INTO `CATable` "
1828 "( `Action`, `Type` ) "
1829 "VALUES ( 'build', 32)");
1830 ok(r == S_OK, "cannot add entry to CATable table:%d\n", r );
1832 r = run_query(hdb, 0, "INSERT INTO `CATable` "
1833 "( `Action`, `Type` ) "
1834 "VALUES ( 'depends', 64)");
1835 ok(r == S_OK, "cannot add entry to CATable table:%d\n", r );
1837 r = run_query(hdb, 0, "INSERT INTO `CATable` "
1838 "( `Action`, `Type` ) "
1839 "VALUES ( 'clean', 63)");
1840 ok(r == S_OK, "cannot add entry to CATable table:%d\n", r );
1842 r = run_query(hdb, 0, "INSERT INTO `CATable` "
1843 "( `Action`, `Type` ) "
1844 "VALUES ( 'build2', 34)");
1845 ok(r == S_OK, "cannot add entry to CATable table:%d\n", r );
1846 query = "Select IESTable.Condition from CATable, IESTable where "
1847 "CATable.Action = IESTable.Action and CATable.Type = 32";
1848 r = MsiDatabaseOpenView(hdb, query, &view);
1849 ok( r == ERROR_SUCCESS, "failed to open view: %d\n", r );
1851 r = MsiViewExecute(view, 0);
1852 ok( r == ERROR_SUCCESS, "failed to execute view: %d\n", r );
1854 r = MsiViewFetch(view, &rec);
1855 ok( r == ERROR_SUCCESS, "failed to fetch view: %d\n", r );
1857 ok( check_record( rec, 1, "cond2"), "wrong condition\n");
1859 MsiCloseHandle( rec );
1860 r = MsiViewFetch(view, &rec);
1861 ok( r == ERROR_SUCCESS, "failed to fetch view: %d\n", r );
1863 ok( check_record( rec, 1, "cond3"), "wrong condition\n");
1865 MsiCloseHandle( rec );
1867 MsiCloseHandle(view);
1869 MsiCloseHandle( hdb );
1870 DeleteFile(msifile);
1875 static void test_where(void)
1877 MSIHANDLE hdb = 0, rec, view;
1885 ok( hdb, "failed to create db\n");
1887 r = run_query( hdb, 0,
1888 "CREATE TABLE `Media` ("
1889 "`DiskId` SHORT NOT NULL, "
1890 "`LastSequence` LONG, "
1891 "`DiskPrompt` CHAR(64) LOCALIZABLE, "
1892 "`Cabinet` CHAR(255), "
1893 "`VolumeLabel` CHAR(32), "
1894 "`Source` CHAR(72) "
1895 "PRIMARY KEY `DiskId`)" );
1896 ok( r == S_OK, "cannot create Media table: %d\n", r );
1898 r = run_query( hdb, 0, "INSERT INTO `Media` "
1899 "( `DiskId`, `LastSequence`, `DiskPrompt`, `Cabinet`, `VolumeLabel`, `Source` ) "
1900 "VALUES ( 1, 0, '', 'zero.cab', '', '' )" );
1901 ok( r == S_OK, "cannot add file to the Media table: %d\n", r );
1903 r = run_query( hdb, 0, "INSERT INTO `Media` "
1904 "( `DiskId`, `LastSequence`, `DiskPrompt`, `Cabinet`, `VolumeLabel`, `Source` ) "
1905 "VALUES ( 2, 1, '', 'one.cab', '', '' )" );
1906 ok( r == S_OK, "cannot add file to the Media table: %d\n", r );
1908 r = run_query( hdb, 0, "INSERT INTO `Media` "
1909 "( `DiskId`, `LastSequence`, `DiskPrompt`, `Cabinet`, `VolumeLabel`, `Source` ) "
1910 "VALUES ( 3, 2, '', 'two.cab', '', '' )" );
1911 ok( r == S_OK, "cannot add file to the Media table: %d\n", r );
1913 query = "SELECT * FROM `Media`";
1914 r = do_query(hdb, query, &rec);
1915 ok(r == ERROR_SUCCESS, "MsiViewFetch failed: %d\n", r);
1916 ok( check_record( rec, 4, "zero.cab"), "wrong cabinet\n");
1917 MsiCloseHandle( rec );
1919 query = "SELECT * FROM `Media` WHERE `LastSequence` >= 1";
1920 r = do_query(hdb, query, &rec);
1921 ok(r == ERROR_SUCCESS, "MsiViewFetch failed: %d\n", r);
1922 ok( check_record( rec, 4, "one.cab"), "wrong cabinet\n");
1924 r = MsiRecordGetInteger(rec, 1);
1925 ok( 2 == r, "field wrong\n");
1926 r = MsiRecordGetInteger(rec, 2);
1927 ok( 1 == r, "field wrong\n");
1928 MsiCloseHandle( rec );
1930 query = "SELECT `DiskId` FROM `Media` WHERE `LastSequence` >= 1 AND DiskId >= 0";
1931 r = MsiDatabaseOpenView(hdb, query, &view);
1932 ok( r == ERROR_SUCCESS, "failed to open view: %d\n", r );
1934 r = MsiViewExecute(view, 0);
1935 ok( r == ERROR_SUCCESS, "failed to execute view: %d\n", r );
1937 r = MsiViewFetch(view, &rec);
1938 ok( r == ERROR_SUCCESS, "failed to fetch view: %d\n", r );
1940 count = MsiRecordGetFieldCount( rec );
1941 ok( count == 1, "Expected 1 record fields, got %d\n", count );
1944 r = MsiRecordGetString( rec, 1, buf, &size );
1945 ok( r == ERROR_SUCCESS, "failed to get record string: %d\n", r );
1946 ok( !lstrcmp( buf, "2" ),
1947 "For (row %d, column 1) expected '%d', got %s\n", 0, 2, buf );
1948 MsiCloseHandle( rec );
1950 r = MsiViewFetch(view, &rec);
1951 ok( r == ERROR_SUCCESS, "failed to fetch view: %d\n", r );
1954 r = MsiRecordGetString( rec, 1, buf, &size );
1955 ok( r == ERROR_SUCCESS, "failed to get record string: %d\n", r );
1956 ok( !lstrcmp( buf, "3" ),
1957 "For (row %d, column 1) expected '%d', got %s\n", 1, 3, buf );
1958 MsiCloseHandle( rec );
1960 r = MsiViewFetch(view, &rec);
1961 ok( r == ERROR_NO_MORE_ITEMS, "expected no more items: %d\n", r );
1964 MsiCloseHandle(view);
1966 MsiCloseHandle( rec );
1969 query = "SELECT * FROM `Media` WHERE `DiskPrompt` IS NULL";
1970 r = do_query(hdb, query, &rec);
1971 ok( r == ERROR_SUCCESS, "query failed: %d\n", r );
1972 MsiCloseHandle( rec );
1975 query = "SELECT * FROM `Media` WHERE `DiskPrompt` < 'Cabinet'";
1976 r = do_query(hdb, query, &rec);
1977 ok( r == ERROR_BAD_QUERY_SYNTAX, "query failed: %d\n", r );
1978 MsiCloseHandle( rec );
1981 query = "SELECT * FROM `Media` WHERE `DiskPrompt` > 'Cabinet'";
1982 r = do_query(hdb, query, &rec);
1983 ok( r == ERROR_BAD_QUERY_SYNTAX, "query failed: %d\n", r );
1984 MsiCloseHandle( rec );
1987 query = "SELECT * FROM `Media` WHERE `DiskPrompt` <> 'Cabinet'";
1988 r = do_query(hdb, query, &rec);
1989 ok( r == ERROR_SUCCESS, "query failed: %d\n", r );
1990 MsiCloseHandle( rec );
1993 query = "SELECT * FROM `Media` WHERE `DiskPrompt` = 'Cabinet'";
1994 r = do_query(hdb, query, &rec);
1995 ok( r == ERROR_NO_MORE_ITEMS, "query failed: %d\n", r );
1996 MsiCloseHandle( rec );
1998 rec = MsiCreateRecord(1);
1999 MsiRecordSetString(rec, 1, "");
2001 query = "SELECT * FROM `Media` WHERE `DiskPrompt` = ?";
2002 r = MsiDatabaseOpenView(hdb, query, &view);
2003 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2004 r = MsiViewExecute(view, rec);
2005 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2007 MsiCloseHandle(rec);
2009 r = MsiViewFetch(view, &rec);
2010 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2012 MsiCloseHandle(rec);
2014 MsiCloseHandle(view);
2016 MsiCloseHandle( hdb );
2017 DeleteFile(msifile);
2020 static CHAR CURR_DIR[MAX_PATH];
2022 static const CHAR test_data[] = "FirstPrimaryColumn\tSecondPrimaryColumn\tShortInt\tShortIntNullable\tLongInt\tLongIntNullable\tString\tLocalizableString\tLocalizableStringNullable\n"
2023 "s255\ti2\ti2\tI2\ti4\tI4\tS255\tS0\ts0\n"
2024 "TestTable\tFirstPrimaryColumn\n"
2025 "stringage\t5\t2\t\t2147483640\t-2147483640\tanother string\tlocalizable\tduh\n";
2027 static const CHAR two_primary[] = "PrimaryOne\tPrimaryTwo\n"
2029 "TwoPrimary\tPrimaryOne\tPrimaryTwo\n"
2033 static const CHAR endlines1[] = "A\tB\tC\tD\tE\tF\r\n"
2034 "s72\ts72\ts72\ts72\ts72\ts72\n"
2036 "a\tb\tc\td\te\tf\n"
2037 "g\th\ti\t\rj\tk\tl\r\n";
2039 static const CHAR endlines2[] = "A\tB\tC\tD\tE\tF\r"
2040 "s72\ts72\ts72\ts72\ts72\ts72\n"
2042 "a\tb\tc\td\te\tf\n"
2043 "g\th\ti\tj\tk\tl\r\n";
2045 static const CHAR suminfo[] = "PropertyId\tValue\n"
2047 "_SummaryInformation\tPropertyId\n"
2049 "2\tInstaller Database\n"
2050 "3\tInstaller description\n"
2053 "6\tInstaller comments\n"
2054 "7\tIntel;1033,2057\n"
2055 "9\t{12345678-1234-1234-1234-123456789012}\n"
2056 "12\t2009/04/12 15:46:11\n"
2057 "13\t2009/04/12 15:46:11\n"
2063 static void write_file(const CHAR *filename, const char *data, int data_size)
2067 HANDLE hf = CreateFile(filename, GENERIC_WRITE, 0, NULL,
2068 CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
2070 WriteFile(hf, data, data_size, &size, NULL);
2074 static UINT add_table_to_db(MSIHANDLE hdb, LPCSTR table_data)
2078 write_file("temp_file", table_data, (lstrlen(table_data) - 1) * sizeof(char));
2079 r = MsiDatabaseImportA(hdb, CURR_DIR, "temp_file");
2080 DeleteFileA("temp_file");
2085 static void test_suminfo_import(void)
2087 MSIHANDLE hdb, hsi, view = 0;
2089 UINT r, count, size, type;
2094 GetCurrentDirectoryA(MAX_PATH, CURR_DIR);
2096 r = MsiOpenDatabaseA(msifile, MSIDBOPEN_CREATE, &hdb);
2097 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2099 r = add_table_to_db(hdb, suminfo);
2100 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2102 /* _SummaryInformation is not imported as a regular table... */
2104 query = "SELECT * FROM `_SummaryInformation`";
2105 r = MsiDatabaseOpenViewA(hdb, query, &view);
2106 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %u\n", r);
2107 MsiCloseHandle(view);
2109 /* ...its data is added to the special summary information stream */
2111 r = MsiGetSummaryInformationA(hdb, NULL, 0, &hsi);
2112 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2114 r = MsiSummaryInfoGetPropertyCount(hsi, &count);
2115 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2116 ok(count == 14, "Expected 14, got %u\n", count);
2118 r = MsiSummaryInfoGetPropertyA(hsi, PID_CODEPAGE, &type, &int_value, NULL, NULL, NULL);
2119 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2120 ok(type == VT_I2, "Expected VT_I2, got %u\n", type);
2121 ok(int_value == 1252, "Expected 1252, got %d\n", int_value);
2123 size = sizeof(str_value);
2124 r = MsiSummaryInfoGetPropertyA(hsi, PID_TITLE, &type, NULL, NULL, str_value, &size);
2125 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2126 ok(type == VT_LPSTR, "Expected VT_LPSTR, got %u\n", type);
2127 ok(size == 18, "Expected 18, got %u\n", size);
2128 ok(!strcmp(str_value, "Installer Database"),
2129 "Expected \"Installer Database\", got %s\n", str_value);
2131 size = sizeof(str_value);
2132 r = MsiSummaryInfoGetPropertyA(hsi, PID_SUBJECT, &type, NULL, NULL, str_value, &size);
2133 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2134 ok(type == VT_LPSTR, "Expected VT_LPSTR, got %u\n", type);
2135 ok(!strcmp(str_value, "Installer description"),
2136 "Expected \"Installer description\", got %s\n", str_value);
2138 size = sizeof(str_value);
2139 r = MsiSummaryInfoGetPropertyA(hsi, PID_AUTHOR, &type, NULL, NULL, str_value, &size);
2140 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2141 ok(type == VT_LPSTR, "Expected VT_LPSTR, got %u\n", type);
2142 ok(!strcmp(str_value, "WineHQ"),
2143 "Expected \"WineHQ\", got %s\n", str_value);
2145 size = sizeof(str_value);
2146 r = MsiSummaryInfoGetPropertyA(hsi, PID_KEYWORDS, &type, NULL, NULL, str_value, &size);
2147 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2148 ok(type == VT_LPSTR, "Expected VT_LPSTR, got %u\n", type);
2149 ok(!strcmp(str_value, "Installer"),
2150 "Expected \"Installer\", got %s\n", str_value);
2152 size = sizeof(str_value);
2153 r = MsiSummaryInfoGetPropertyA(hsi, PID_COMMENTS, &type, NULL, NULL, str_value, &size);
2154 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2155 ok(type == VT_LPSTR, "Expected VT_LPSTR, got %u\n", type);
2156 ok(!strcmp(str_value, "Installer comments"),
2157 "Expected \"Installer comments\", got %s\n", str_value);
2159 size = sizeof(str_value);
2160 r = MsiSummaryInfoGetPropertyA(hsi, PID_TEMPLATE, &type, NULL, NULL, str_value, &size);
2161 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2162 ok(type == VT_LPSTR, "Expected VT_LPSTR, got %u\n", type);
2163 ok(!strcmp(str_value, "Intel;1033,2057"),
2164 "Expected \"Intel;1033,2057\", got %s\n", str_value);
2166 size = sizeof(str_value);
2167 r = MsiSummaryInfoGetPropertyA(hsi, PID_REVNUMBER, &type, NULL, NULL, str_value, &size);
2168 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2169 ok(type == VT_LPSTR, "Expected VT_LPSTR, got %u\n", type);
2170 ok(!strcmp(str_value, "{12345678-1234-1234-1234-123456789012}"),
2171 "Expected \"{12345678-1234-1234-1234-123456789012}\", got %s\n", str_value);
2173 r = MsiSummaryInfoGetPropertyA(hsi, PID_CREATE_DTM, &type, NULL, &ft_value, NULL, NULL);
2174 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2175 ok(type == VT_FILETIME, "Expected VT_FILETIME, got %u\n", type);
2177 r = MsiSummaryInfoGetPropertyA(hsi, PID_LASTSAVE_DTM, &type, NULL, &ft_value, NULL, NULL);
2178 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2179 ok(type == VT_FILETIME, "Expected VT_FILETIME, got %u\n", type);
2181 r = MsiSummaryInfoGetPropertyA(hsi, PID_PAGECOUNT, &type, &int_value, NULL, NULL, NULL);
2182 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2183 ok(type == VT_I4, "Expected VT_I4, got %u\n", type);
2184 ok(int_value == 200, "Expected 200, got %d\n", int_value);
2186 r = MsiSummaryInfoGetPropertyA(hsi, PID_WORDCOUNT, &type, &int_value, NULL, NULL, NULL);
2187 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2188 ok(type == VT_I4, "Expected VT_I4, got %u\n", type);
2189 ok(int_value == 2, "Expected 2, got %d\n", int_value);
2191 r = MsiSummaryInfoGetPropertyA(hsi, PID_SECURITY, &type, &int_value, NULL, NULL, NULL);
2192 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2193 ok(type == VT_I4, "Expected VT_I4, got %u\n", type);
2194 ok(int_value == 2, "Expected 2, got %d\n", int_value);
2196 size = sizeof(str_value);
2197 r = MsiSummaryInfoGetPropertyA(hsi, PID_APPNAME, &type, NULL, NULL, str_value, &size);
2198 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2199 ok(type == VT_LPSTR, "Expected VT_LPSTR, got %u\n", type);
2200 ok(!strcmp(str_value, "Vim"), "Expected \"Vim\", got %s\n", str_value);
2202 MsiCloseHandle(hsi);
2203 MsiCloseHandle(hdb);
2204 DeleteFileA(msifile);
2207 static void test_msiimport(void)
2209 MSIHANDLE hdb, view, rec;
2214 GetCurrentDirectoryA(MAX_PATH, CURR_DIR);
2216 r = MsiOpenDatabaseA(msifile, MSIDBOPEN_CREATE, &hdb);
2217 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2219 r = add_table_to_db(hdb, test_data);
2220 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2222 r = add_table_to_db(hdb, two_primary);
2223 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2225 r = add_table_to_db(hdb, endlines1);
2226 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2228 r = add_table_to_db(hdb, endlines2);
2229 ok(r == ERROR_FUNCTION_FAILED, "Expected ERROR_FUNCTION_FAILED, got %d\n", r);
2231 query = "SELECT * FROM `TestTable`";
2232 r = MsiDatabaseOpenView(hdb, query, &view);
2233 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2235 r = MsiViewGetColumnInfo(view, MSICOLINFO_NAMES, &rec);
2236 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2237 count = MsiRecordGetFieldCount(rec);
2238 ok(count == 9, "Expected 9, got %d\n", count);
2239 ok(check_record(rec, 1, "FirstPrimaryColumn"), "Expected FirstPrimaryColumn\n");
2240 ok(check_record(rec, 2, "SecondPrimaryColumn"), "Expected SecondPrimaryColumn\n");
2241 ok(check_record(rec, 3, "ShortInt"), "Expected ShortInt\n");
2242 ok(check_record(rec, 4, "ShortIntNullable"), "Expected ShortIntNullalble\n");
2243 ok(check_record(rec, 5, "LongInt"), "Expected LongInt\n");
2244 ok(check_record(rec, 6, "LongIntNullable"), "Expected LongIntNullalble\n");
2245 ok(check_record(rec, 7, "String"), "Expected String\n");
2246 ok(check_record(rec, 8, "LocalizableString"), "Expected LocalizableString\n");
2247 ok(check_record(rec, 9, "LocalizableStringNullable"), "Expected LocalizableStringNullable\n");
2248 MsiCloseHandle(rec);
2250 r = MsiViewGetColumnInfo(view, MSICOLINFO_TYPES, &rec);
2251 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2252 count = MsiRecordGetFieldCount(rec);
2253 ok(count == 9, "Expected 9, got %d\n", count);
2254 ok(check_record(rec, 1, "s255"), "Expected s255\n");
2255 ok(check_record(rec, 2, "i2"), "Expected i2\n");
2256 ok(check_record(rec, 3, "i2"), "Expected i2\n");
2257 ok(check_record(rec, 4, "I2"), "Expected I2\n");
2258 ok(check_record(rec, 5, "i4"), "Expected i4\n");
2259 ok(check_record(rec, 6, "I4"), "Expected I4\n");
2260 ok(check_record(rec, 7, "S255"), "Expected S255\n");
2261 ok(check_record(rec, 8, "S0"), "Expected S0\n");
2262 ok(check_record(rec, 9, "s0"), "Expected s0\n");
2263 MsiCloseHandle(rec);
2265 query = "SELECT * FROM `TestTable`";
2266 r = do_query(hdb, query, &rec);
2267 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2268 ok(check_record(rec, 1, "stringage"), "Expected 'stringage'\n");
2269 ok(check_record(rec, 7, "another string"), "Expected 'another string'\n");
2270 ok(check_record(rec, 8, "localizable"), "Expected 'localizable'\n");
2271 ok(check_record(rec, 9, "duh"), "Expected 'duh'\n");
2273 i = MsiRecordGetInteger(rec, 2);
2274 ok(i == 5, "Expected 5, got %d\n", i);
2276 i = MsiRecordGetInteger(rec, 3);
2277 ok(i == 2, "Expected 2, got %d\n", i);
2279 i = MsiRecordGetInteger(rec, 4);
2280 ok(i == MSI_NULL_INTEGER, "Expected MSI_NULL_INTEGER, got %d\n", i);
2282 i = MsiRecordGetInteger(rec, 5);
2283 ok(i == 2147483640, "Expected 2147483640, got %d\n", i);
2285 i = MsiRecordGetInteger(rec, 6);
2286 ok(i == -2147483640, "Expected -2147483640, got %d\n", i);
2288 MsiCloseHandle(rec);
2290 MsiCloseHandle(view);
2292 query = "SELECT * FROM `TwoPrimary`";
2293 r = MsiDatabaseOpenView(hdb, query, &view);
2294 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2296 r = MsiViewGetColumnInfo(view, MSICOLINFO_NAMES, &rec);
2297 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2298 count = MsiRecordGetFieldCount(rec);
2299 ok(count == 2, "Expected 2, got %d\n", count);
2300 ok(check_record(rec, 1, "PrimaryOne"), "Expected PrimaryOne\n");
2301 ok(check_record(rec, 2, "PrimaryTwo"), "Expected PrimaryTwo\n");
2303 MsiCloseHandle(rec);
2305 r = MsiViewGetColumnInfo(view, MSICOLINFO_TYPES, &rec);
2306 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2307 count = MsiRecordGetFieldCount(rec);
2308 ok(count == 2, "Expected 2, got %d\n", count);
2309 ok(check_record(rec, 1, "s255"), "Expected s255\n");
2310 ok(check_record(rec, 2, "s255"), "Expected s255\n");
2311 MsiCloseHandle(rec);
2313 r = MsiViewExecute(view, 0);
2314 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2316 r = MsiViewFetch(view, &rec);
2317 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2319 ok(check_record(rec, 1, "papaya"), "Expected 'papaya'\n");
2320 ok(check_record(rec, 2, "leaf"), "Expected 'leaf'\n");
2322 MsiCloseHandle(rec);
2324 r = MsiViewFetch(view, &rec);
2325 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2327 ok(check_record(rec, 1, "papaya"), "Expected 'papaya'\n");
2328 ok(check_record(rec, 2, "flower"), "Expected 'flower'\n");
2330 MsiCloseHandle(rec);
2332 r = MsiViewFetch(view, &rec);
2333 ok(r == ERROR_NO_MORE_ITEMS,
2334 "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
2336 r = MsiViewClose(view);
2337 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2339 MsiCloseHandle(view);
2341 query = "SELECT * FROM `Table`";
2342 r = MsiDatabaseOpenView(hdb, query, &view);
2343 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2345 r = MsiViewGetColumnInfo(view, MSICOLINFO_NAMES, &rec);
2346 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2347 count = MsiRecordGetFieldCount(rec);
2348 ok(count == 6, "Expected 6, got %d\n", count);
2349 ok(check_record(rec, 1, "A"), "Expected A\n");
2350 ok(check_record(rec, 2, "B"), "Expected B\n");
2351 ok(check_record(rec, 3, "C"), "Expected C\n");
2352 ok(check_record(rec, 4, "D"), "Expected D\n");
2353 ok(check_record(rec, 5, "E"), "Expected E\n");
2354 ok(check_record(rec, 6, "F"), "Expected F\n");
2355 MsiCloseHandle(rec);
2357 r = MsiViewGetColumnInfo(view, MSICOLINFO_TYPES, &rec);
2358 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2359 count = MsiRecordGetFieldCount(rec);
2360 ok(count == 6, "Expected 6, got %d\n", count);
2361 ok(check_record(rec, 1, "s72"), "Expected s72\n");
2362 ok(check_record(rec, 2, "s72"), "Expected s72\n");
2363 ok(check_record(rec, 3, "s72"), "Expected s72\n");
2364 ok(check_record(rec, 4, "s72"), "Expected s72\n");
2365 ok(check_record(rec, 5, "s72"), "Expected s72\n");
2366 ok(check_record(rec, 6, "s72"), "Expected s72\n");
2367 MsiCloseHandle(rec);
2370 MsiCloseHandle(view);
2372 query = "SELECT * FROM `Table`";
2373 r = MsiDatabaseOpenView(hdb, query, &view);
2374 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2376 r = MsiViewExecute(view, 0);
2377 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2379 r = MsiViewFetch(view, &rec);
2380 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2381 ok(check_record(rec, 1, "a"), "Expected 'a'\n");
2382 ok(check_record(rec, 2, "b"), "Expected 'b'\n");
2383 ok(check_record(rec, 3, "c"), "Expected 'c'\n");
2384 ok(check_record(rec, 4, "d"), "Expected 'd'\n");
2385 ok(check_record(rec, 5, "e"), "Expected 'e'\n");
2386 ok(check_record(rec, 6, "f"), "Expected 'f'\n");
2388 MsiCloseHandle(rec);
2390 r = MsiViewFetch(view, &rec);
2391 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2392 ok(check_record(rec, 1, "g"), "Expected 'g'\n");
2393 ok(check_record(rec, 2, "h"), "Expected 'h'\n");
2394 ok(check_record(rec, 3, "i"), "Expected 'i'\n");
2395 ok(check_record(rec, 4, "j"), "Expected 'j'\n");
2396 ok(check_record(rec, 5, "k"), "Expected 'k'\n");
2397 ok(check_record(rec, 6, "l"), "Expected 'l'\n");
2399 MsiCloseHandle(rec);
2401 r = MsiViewFetch(view, &rec);
2402 ok(r == ERROR_NO_MORE_ITEMS,
2403 "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
2406 MsiCloseHandle(view);
2407 MsiCloseHandle(hdb);
2408 DeleteFileA(msifile);
2411 static const CHAR bin_import_dat[] = "Name\tData\r\n"
2414 "filename1\tfilename1.ibd\r\n";
2416 static void test_binary_import(void)
2418 MSIHANDLE hdb = 0, rec;
2419 char file[MAX_PATH];
2421 char path[MAX_PATH];
2426 /* create files to import */
2427 write_file("bin_import.idt", bin_import_dat,
2428 (sizeof(bin_import_dat) - 1) * sizeof(char));
2429 CreateDirectory("bin_import", NULL);
2430 create_file_data("bin_import/filename1.ibd", "just some words", 15);
2432 /* import files into database */
2433 r = MsiOpenDatabase(msifile, MSIDBOPEN_CREATE, &hdb);
2434 ok( r == ERROR_SUCCESS , "Failed to open database\n");
2436 GetCurrentDirectory(MAX_PATH, path);
2437 r = MsiDatabaseImport(hdb, path, "bin_import.idt");
2438 ok(r == ERROR_SUCCESS , "Failed to import Binary table\n");
2440 /* read file from the Binary table */
2441 query = "SELECT * FROM `Binary`";
2442 r = do_query(hdb, query, &rec);
2443 ok(r == ERROR_SUCCESS, "SELECT query failed: %d\n", r);
2446 r = MsiRecordGetString(rec, 1, file, &size);
2447 ok(r == ERROR_SUCCESS, "Failed to get string: %d\n", r);
2448 ok(!lstrcmp(file, "filename1"), "Expected 'filename1', got %s\n", file);
2451 memset(buf, 0, MAX_PATH);
2452 r = MsiRecordReadStream(rec, 2, buf, &size);
2453 ok(r == ERROR_SUCCESS, "Failed to get stream: %d\n", r);
2454 ok(!lstrcmp(buf, "just some words"),
2455 "Expected 'just some words', got %s\n", buf);
2457 r = MsiCloseHandle(rec);
2458 ok(r == ERROR_SUCCESS , "Failed to close record handle\n");
2460 r = MsiCloseHandle(hdb);
2461 ok(r == ERROR_SUCCESS , "Failed to close database\n");
2463 DeleteFile("bin_import/filename1.ibd");
2464 RemoveDirectory("bin_import");
2465 DeleteFile("bin_import.idt");
2468 static void test_markers(void)
2475 ok( hdb, "failed to create db\n");
2477 rec = MsiCreateRecord(3);
2478 MsiRecordSetString(rec, 1, "Table");
2479 MsiRecordSetString(rec, 2, "Apples");
2480 MsiRecordSetString(rec, 3, "Oranges");
2482 /* try a legit create */
2483 query = "CREATE TABLE `Table` ( `One` SHORT NOT NULL, `Two` CHAR(255) PRIMARY KEY `One`)";
2484 r = run_query(hdb, 0, query);
2485 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2486 MsiCloseHandle(rec);
2488 /* try table name as marker */
2489 rec = MsiCreateRecord(1);
2490 MsiRecordSetString(rec, 1, "Fable");
2491 query = "CREATE TABLE `?` ( `One` SHORT NOT NULL, `Two` CHAR(255) PRIMARY KEY `One`)";
2492 r = run_query(hdb, rec, query);
2493 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2495 /* verify that we just created a table called '?', not 'Fable' */
2496 r = try_query(hdb, "SELECT * from `Fable`");
2497 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
2499 r = try_query(hdb, "SELECT * from `?`");
2500 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2502 /* try table name as marker without backticks */
2503 MsiRecordSetString(rec, 1, "Mable");
2504 query = "CREATE TABLE ? ( `One` SHORT NOT NULL, `Two` CHAR(255) PRIMARY KEY `One`)";
2505 r = run_query(hdb, rec, query);
2506 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
2508 /* try one column name as marker */
2509 MsiRecordSetString(rec, 1, "One");
2510 query = "CREATE TABLE `Mable` ( `?` SHORT NOT NULL, `Two` CHAR(255) PRIMARY KEY `One`)";
2511 r = run_query(hdb, rec, query);
2512 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
2513 MsiCloseHandle(rec);
2515 /* try column names as markers */
2516 rec = MsiCreateRecord(2);
2517 MsiRecordSetString(rec, 1, "One");
2518 MsiRecordSetString(rec, 2, "Two");
2519 query = "CREATE TABLE `Mable` ( `?` SHORT NOT NULL, `?` CHAR(255) PRIMARY KEY `One`)";
2520 r = run_query(hdb, rec, query);
2521 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
2522 MsiCloseHandle(rec);
2524 /* try names with backticks */
2525 rec = MsiCreateRecord(3);
2526 MsiRecordSetString(rec, 1, "One");
2527 MsiRecordSetString(rec, 2, "Two");
2528 MsiRecordSetString(rec, 3, "One");
2529 query = "CREATE TABLE `Mable` ( `?` SHORT NOT NULL, `?` CHAR(255) PRIMARY KEY `?`)";
2530 r = run_query(hdb, rec, query);
2531 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
2533 /* try names with backticks, minus definitions */
2534 query = "CREATE TABLE `Mable` ( `?`, `?` PRIMARY KEY `?`)";
2535 r = run_query(hdb, rec, query);
2536 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
2538 /* try names without backticks */
2539 query = "CREATE TABLE `Mable` ( ? SHORT NOT NULL, ? CHAR(255) PRIMARY KEY ?)";
2540 r = run_query(hdb, rec, query);
2541 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
2542 MsiCloseHandle(rec);
2544 /* try one long marker */
2545 rec = MsiCreateRecord(1);
2546 MsiRecordSetString(rec, 1, "`One` SHORT NOT NULL, `Two` CHAR(255) PRIMARY KEY `One`");
2547 query = "CREATE TABLE `Mable` ( ? )";
2548 r = run_query(hdb, rec, query);
2549 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
2550 MsiCloseHandle(rec);
2552 /* try all names as markers */
2553 rec = MsiCreateRecord(4);
2554 MsiRecordSetString(rec, 1, "Mable");
2555 MsiRecordSetString(rec, 2, "One");
2556 MsiRecordSetString(rec, 3, "Two");
2557 MsiRecordSetString(rec, 4, "One");
2558 query = "CREATE TABLE `?` ( `?` SHORT NOT NULL, `?` CHAR(255) PRIMARY KEY `?`)";
2559 r = run_query(hdb, rec, query);
2560 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
2561 MsiCloseHandle(rec);
2563 /* try a legit insert */
2564 query = "INSERT INTO `Table` ( `One`, `Two` ) VALUES ( 5, 'hello' )";
2565 r = run_query(hdb, 0, query);
2566 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2568 r = try_query(hdb, "SELECT * from `Table`");
2569 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2571 /* try values as markers */
2572 rec = MsiCreateRecord(2);
2573 MsiRecordSetInteger(rec, 1, 4);
2574 MsiRecordSetString(rec, 2, "hi");
2575 query = "INSERT INTO `Table` ( `One`, `Two` ) VALUES ( ?, '?' )";
2576 r = run_query(hdb, rec, query);
2577 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2578 MsiCloseHandle(rec);
2580 /* try column names and values as markers */
2581 rec = MsiCreateRecord(4);
2582 MsiRecordSetString(rec, 1, "One");
2583 MsiRecordSetString(rec, 2, "Two");
2584 MsiRecordSetInteger(rec, 3, 5);
2585 MsiRecordSetString(rec, 4, "hi");
2586 query = "INSERT INTO `Table` ( `?`, `?` ) VALUES ( ?, '?' )";
2587 r = run_query(hdb, rec, query);
2588 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
2589 MsiCloseHandle(rec);
2591 /* try column names as markers */
2592 rec = MsiCreateRecord(2);
2593 MsiRecordSetString(rec, 1, "One");
2594 MsiRecordSetString(rec, 2, "Two");
2595 query = "INSERT INTO `Table` ( `?`, `?` ) VALUES ( 3, 'yellow' )";
2596 r = run_query(hdb, rec, query);
2597 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
2598 MsiCloseHandle(rec);
2600 /* try table name as a marker */
2601 rec = MsiCreateRecord(1);
2602 MsiRecordSetString(rec, 1, "Table");
2603 query = "INSERT INTO `?` ( `One`, `Two` ) VALUES ( 2, 'green' )";
2604 r = run_query(hdb, rec, query);
2605 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2606 MsiCloseHandle(rec);
2608 /* try table name and values as markers */
2609 rec = MsiCreateRecord(3);
2610 MsiRecordSetString(rec, 1, "Table");
2611 MsiRecordSetInteger(rec, 2, 10);
2612 MsiRecordSetString(rec, 3, "haha");
2613 query = "INSERT INTO `?` ( `One`, `Two` ) VALUES ( ?, '?' )";
2614 r = run_query(hdb, rec, query);
2615 ok(r == ERROR_FUNCTION_FAILED, "Expected ERROR_FUNCTION_FAILED, got %d\n", r);
2616 MsiCloseHandle(rec);
2618 /* try all markers */
2619 rec = MsiCreateRecord(5);
2620 MsiRecordSetString(rec, 1, "Table");
2621 MsiRecordSetString(rec, 1, "One");
2622 MsiRecordSetString(rec, 1, "Two");
2623 MsiRecordSetInteger(rec, 2, 10);
2624 MsiRecordSetString(rec, 3, "haha");
2625 query = "INSERT INTO `?` ( `?`, `?` ) VALUES ( ?, '?' )";
2626 r = run_query(hdb, rec, query);
2627 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
2628 MsiCloseHandle(rec);
2630 /* insert an integer as a string */
2631 rec = MsiCreateRecord(2);
2632 MsiRecordSetString(rec, 1, "11");
2633 MsiRecordSetString(rec, 2, "hi");
2634 query = "INSERT INTO `Table` ( `One`, `Two` ) VALUES ( ?, '?' )";
2635 r = run_query(hdb, rec, query);
2636 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2637 MsiCloseHandle(rec);
2639 /* leave off the '' for the string */
2640 rec = MsiCreateRecord(2);
2641 MsiRecordSetInteger(rec, 1, 12);
2642 MsiRecordSetString(rec, 2, "hi");
2643 query = "INSERT INTO `Table` ( `One`, `Two` ) VALUES ( ?, ? )";
2644 r = run_query(hdb, rec, query);
2645 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2646 MsiCloseHandle(rec);
2648 MsiCloseHandle(hdb);
2649 DeleteFileA(msifile);
2652 #define MY_NVIEWS 4000 /* Largest installer I've seen uses < 2k */
2653 static void test_handle_limit(void)
2657 MSIHANDLE hviews[MY_NVIEWS];
2660 /* create an empty db */
2662 ok( hdb, "failed to create db\n");
2664 memset(hviews, 0, sizeof(hviews));
2666 for (i=0; i<MY_NVIEWS; i++) {
2667 static char szQueryBuf[256] = "SELECT * from `_Tables`";
2668 hviews[i] = 0xdeadbeeb;
2669 r = MsiDatabaseOpenView(hdb, szQueryBuf, &hviews[i]);
2670 if( r != ERROR_SUCCESS || hviews[i] == 0xdeadbeeb ||
2671 hviews[i] == 0 || (i && (hviews[i] == hviews[i-1])))
2675 ok( i == MY_NVIEWS, "problem opening views\n");
2677 for (i=0; i<MY_NVIEWS; i++) {
2678 if (hviews[i] != 0 && hviews[i] != 0xdeadbeeb) {
2679 MsiViewClose(hviews[i]);
2680 r = MsiCloseHandle(hviews[i]);
2681 if (r != ERROR_SUCCESS)
2686 ok( i == MY_NVIEWS, "problem closing views\n");
2688 r = MsiCloseHandle(hdb);
2689 ok( r == ERROR_SUCCESS, "failed to close database\n");
2692 static void generate_transform(void)
2694 MSIHANDLE hdb1, hdb2, hrec;
2698 /* start with two identical databases */
2699 CopyFile(msifile2, msifile, FALSE);
2701 r = MsiOpenDatabase(msifile, MSIDBOPEN_TRANSACT, &hdb1 );
2702 ok( r == ERROR_SUCCESS , "Failed to create database\n" );
2704 r = MsiDatabaseCommit( hdb1 );
2705 ok( r == ERROR_SUCCESS , "Failed to commit database\n" );
2707 r = MsiOpenDatabase(msifile2, MSIDBOPEN_READONLY, &hdb2 );
2708 ok( r == ERROR_SUCCESS , "Failed to create database\n" );
2710 /* the transform between two identical database should be empty */
2711 r = MsiDatabaseGenerateTransform(hdb1, hdb2, NULL, 0, 0);
2713 ok( r == ERROR_NO_DATA, "return code %d, should be ERROR_NO_DATA\n", r );
2716 query = "CREATE TABLE `AAR` ( `BAR` SHORT NOT NULL, `CAR` CHAR(255) PRIMARY KEY `CAR`)";
2717 r = run_query(hdb1, 0, query);
2718 ok(r == ERROR_SUCCESS, "failed to add table\n");
2720 query = "INSERT INTO `AAR` ( `BAR`, `CAR` ) VALUES ( 1, 'vw' )";
2721 r = run_query(hdb1, 0, query);
2722 ok(r == ERROR_SUCCESS, "failed to add row 1\n");
2724 query = "INSERT INTO `AAR` ( `BAR`, `CAR` ) VALUES ( 2, 'bmw' )";
2725 r = run_query(hdb1, 0, query);
2726 ok(r == ERROR_SUCCESS, "failed to add row 2\n");
2728 query = "UPDATE `MOO` SET `OOO` = 'c' WHERE `NOO` = 1";
2729 r = run_query(hdb1, 0, query);
2730 ok(r == ERROR_SUCCESS, "failed to modify row\n");
2732 query = "DELETE FROM `MOO` WHERE `NOO` = 3";
2733 r = run_query(hdb1, 0, query);
2734 ok(r == ERROR_SUCCESS, "failed to delete row\n");
2736 hrec = MsiCreateRecord(2);
2737 r = MsiRecordSetInteger(hrec, 1, 1);
2738 ok(r == ERROR_SUCCESS, "failed to set integer\n");
2740 write_file("testdata.bin", "naengmyon", 9);
2741 r = MsiRecordSetStream(hrec, 2, "testdata.bin");
2742 ok(r == ERROR_SUCCESS, "failed to set stream\n");
2744 query = "INSERT INTO `BINARY` ( `ID`, `BLOB` ) VALUES ( ?, ? )";
2745 r = run_query(hdb1, hrec, query);
2746 ok(r == ERROR_SUCCESS, "failed to add row with blob\n");
2748 MsiCloseHandle(hrec);
2750 query = "ALTER TABLE `MOO` ADD `COW` INTEGER";
2751 r = run_query(hdb1, 0, query);
2752 ok(r == ERROR_SUCCESS, "failed to add column\n");
2754 query = "ALTER TABLE `MOO` ADD `PIG` INTEGER";
2755 r = run_query(hdb1, 0, query);
2756 ok(r == ERROR_SUCCESS, "failed to add column\n");
2758 query = "UPDATE `MOO` SET `PIG` = 5 WHERE `NOO` = 1";
2759 r = run_query(hdb1, 0, query);
2760 ok(r == ERROR_SUCCESS, "failed to modify row\n");
2762 query = "CREATE TABLE `Property` ( `Property` CHAR(72) NOT NULL, "
2763 "`Value` CHAR(0) PRIMARY KEY `Property`)";
2764 r = run_query(hdb1, 0, query);
2765 ok(r == ERROR_SUCCESS, "failed to add property table\n");
2767 query = "INSERT INTO `Property` ( `Property`, `Value` ) VALUES ( 'prop', 'val' )";
2768 r = run_query(hdb1, 0, query);
2769 ok(r == ERROR_SUCCESS, "failed to add property\n");
2771 /* database needs to be committed */
2772 MsiDatabaseCommit(hdb1);
2774 r = MsiDatabaseGenerateTransform(hdb1, hdb2, mstfile, 0, 0);
2775 ok( r == ERROR_SUCCESS, "return code %d, should be ERROR_SUCCESS\n", r );
2777 MsiCloseHandle( hdb1 );
2778 MsiCloseHandle( hdb2 );
2780 DeleteFile("testdata.bin");
2783 /* data for generating a transform */
2785 /* tables transform names - encoded as they would be in an msi database file */
2786 static const WCHAR name1[] = { 0x4840, 0x3a8a, 0x481b, 0 }; /* AAR */
2787 static const WCHAR name2[] = { 0x4840, 0x3b3f, 0x43f2, 0x4438, 0x45b1, 0 }; /* _Columns */
2788 static const WCHAR name3[] = { 0x4840, 0x3f7f, 0x4164, 0x422f, 0x4836, 0 }; /* _Tables */
2789 static const WCHAR name4[] = { 0x4840, 0x3f3f, 0x4577, 0x446c, 0x3b6a, 0x45e4, 0x4824, 0 }; /* _StringData */
2790 static const WCHAR name5[] = { 0x4840, 0x3f3f, 0x4577, 0x446c, 0x3e6a, 0x44b2, 0x482f, 0 }; /* _StringPool */
2791 static const WCHAR name6[] = { 0x4840, 0x3e16, 0x4818, 0}; /* MOO */
2792 static const WCHAR name7[] = { 0x4840, 0x3c8b, 0x3a97, 0x409b, 0 }; /* BINARY */
2793 static const WCHAR name8[] = { 0x3c8b, 0x3a97, 0x409b, 0x387e, 0 }; /* BINARY.1 */
2794 static const WCHAR name9[] = { 0x4840, 0x4559, 0x44f2, 0x4568, 0x4737, 0 }; /* Property */
2796 /* data in each table */
2797 static const WCHAR data1[] = { /* AAR */
2798 0x0201, 0x0008, 0x8001, /* 0x0201 = add row (1), two shorts */
2799 0x0201, 0x0009, 0x8002,
2801 static const WCHAR data2[] = { /* _Columns */
2802 0x0401, 0x0001, 0x8003, 0x0002, 0x9502,
2803 0x0401, 0x0001, 0x8004, 0x0003, 0x9502,
2804 0x0401, 0x0005, 0x0000, 0x0006, 0xbdff, /* 0x0401 = add row (1), 4 shorts */
2805 0x0401, 0x0005, 0x0000, 0x0007, 0x8502,
2806 0x0401, 0x000a, 0x0000, 0x000a, 0xad48,
2807 0x0401, 0x000a, 0x0000, 0x000b, 0x9d00,
2809 static const WCHAR data3[] = { /* _Tables */
2810 0x0101, 0x0005, /* 0x0101 = add row (1), 1 short */
2813 static const char data4[] = /* _StringData */
2814 "MOOCOWPIGcAARCARBARvwbmwPropertyValuepropval"; /* all the strings squashed together */
2815 static const WCHAR data5[] = { /* _StringPool */
2817 0, 0, /* string 0 '' */
2818 3, 2, /* string 1 'MOO' */
2819 3, 1, /* string 2 'COW' */
2820 3, 1, /* string 3 'PIG' */
2821 1, 1, /* string 4 'c' */
2822 3, 3, /* string 5 'AAR' */
2823 3, 1, /* string 6 'CAR' */
2824 3, 1, /* string 7 'BAR' */
2825 2, 1, /* string 8 'vw' */
2826 3, 1, /* string 9 'bmw' */
2827 8, 4, /* string 10 'Property' */
2828 5, 1, /* string 11 'Value' */
2829 4, 1, /* string 12 'prop' */
2830 3, 1, /* string 13 'val' */
2832 /* update row, 0x0002 is a bitmask of present column data, keys are excluded */
2833 static const WCHAR data6[] = { /* MOO */
2834 0x000a, 0x8001, 0x0004, 0x8005, /* update row */
2835 0x0000, 0x8003, /* delete row */
2838 static const WCHAR data7[] = { /* BINARY */
2839 0x0201, 0x8001, 0x0001,
2842 static const char data8[] = /* stream data for the BINARY table */
2845 static const WCHAR data9[] = { /* Property */
2846 0x0201, 0x000c, 0x000d,
2849 static const struct {
2853 } table_transform_data[] =
2855 { name1, data1, sizeof data1 },
2856 { name2, data2, sizeof data2 },
2857 { name3, data3, sizeof data3 },
2858 { name4, data4, sizeof data4 - 1 },
2859 { name5, data5, sizeof data5 },
2860 { name6, data6, sizeof data6 },
2861 { name7, data7, sizeof data7 },
2862 { name8, data8, sizeof data8 - 1 },
2863 { name9, data9, sizeof data9 },
2866 #define NUM_TRANSFORM_TABLES (sizeof table_transform_data/sizeof table_transform_data[0])
2868 static void generate_transform_manual(void)
2870 IStorage *stg = NULL;
2875 const DWORD mode = STGM_CREATE|STGM_READWRITE|STGM_DIRECT|STGM_SHARE_EXCLUSIVE;
2877 const CLSID CLSID_MsiTransform = { 0xc1082,0,0,{0xc0,0,0,0,0,0,0,0x46}};
2879 MultiByteToWideChar(CP_ACP, 0, mstfile, -1, name, 0x20);
2881 r = StgCreateDocfile(name, mode, 0, &stg);
2882 ok(r == S_OK, "failed to create storage\n");
2886 r = IStorage_SetClass( stg, &CLSID_MsiTransform );
2887 ok(r == S_OK, "failed to set storage type\n");
2889 for (i=0; i<NUM_TRANSFORM_TABLES; i++)
2891 r = IStorage_CreateStream( stg, table_transform_data[i].name,
2892 STGM_WRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stm );
2895 ok(0, "failed to create stream %08x\n", r);
2899 r = IStream_Write( stm, table_transform_data[i].data,
2900 table_transform_data[i].size, &count );
2901 if (FAILED(r) || count != table_transform_data[i].size)
2902 ok(0, "failed to write stream\n");
2903 IStream_Release(stm);
2906 IStorage_Release(stg);
2909 static UINT set_summary_info(MSIHANDLE hdb)
2914 /* build summary info */
2915 res = MsiGetSummaryInformation(hdb, NULL, 7, &suminfo);
2916 ok( res == ERROR_SUCCESS , "Failed to open summaryinfo\n" );
2918 res = MsiSummaryInfoSetProperty(suminfo,2, VT_LPSTR, 0,NULL,
2919 "Installation Database");
2920 ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
2922 res = MsiSummaryInfoSetProperty(suminfo,3, VT_LPSTR, 0,NULL,
2923 "Installation Database");
2924 ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
2926 res = MsiSummaryInfoSetProperty(suminfo,4, VT_LPSTR, 0,NULL,
2928 ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
2930 res = MsiSummaryInfoSetProperty(suminfo,7, VT_LPSTR, 0,NULL,
2932 ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
2934 res = MsiSummaryInfoSetProperty(suminfo,9, VT_LPSTR, 0,NULL,
2935 "{913B8D18-FBB6-4CAC-A239-C74C11E3FA74}");
2936 ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
2938 res = MsiSummaryInfoSetProperty(suminfo, 14, VT_I4, 100, NULL, NULL);
2939 ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
2941 res = MsiSummaryInfoSetProperty(suminfo, 15, VT_I4, 0, NULL, NULL);
2942 ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
2944 res = MsiSummaryInfoPersist(suminfo);
2945 ok( res == ERROR_SUCCESS , "Failed to make summary info persist\n" );
2947 res = MsiCloseHandle( suminfo);
2948 ok( res == ERROR_SUCCESS , "Failed to close suminfo\n" );
2953 static MSIHANDLE create_package_db(LPCSTR filename)
2958 DeleteFile(msifile);
2960 /* create an empty database */
2961 res = MsiOpenDatabase(filename, MSIDBOPEN_CREATE, &hdb );
2962 ok( res == ERROR_SUCCESS , "Failed to create database\n" );
2963 if( res != ERROR_SUCCESS )
2966 res = MsiDatabaseCommit( hdb );
2967 ok( res == ERROR_SUCCESS , "Failed to commit database\n" );
2969 res = set_summary_info(hdb);
2970 ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
2972 res = create_directory_table(hdb);
2973 ok( res == ERROR_SUCCESS , "Failed to create directory table\n" );
2978 static UINT package_from_db(MSIHANDLE hdb, MSIHANDLE *handle)
2984 sprintf(szPackage, "#%u", hdb);
2985 res = MsiOpenPackage(szPackage, &hPackage);
2986 if (res != ERROR_SUCCESS)
2989 res = MsiCloseHandle(hdb);
2990 if (res != ERROR_SUCCESS)
2992 MsiCloseHandle(hPackage);
2997 return ERROR_SUCCESS;
3000 static void test_try_transform(void)
3002 MSIHANDLE hdb, hview, hrec, hpkg = 0;
3006 char buffer[MAX_PATH];
3008 DeleteFile(msifile);
3009 DeleteFile(mstfile);
3011 /* create the database */
3012 hdb = create_package_db(msifile);
3013 ok(hdb, "Failed to create package db\n");
3015 query = "CREATE TABLE `MOO` ( `NOO` SHORT NOT NULL, `OOO` CHAR(255) PRIMARY KEY `NOO`)";
3016 r = run_query(hdb, 0, query);
3017 ok(r == ERROR_SUCCESS, "failed to add table\n");
3019 query = "INSERT INTO `MOO` ( `NOO`, `OOO` ) VALUES ( 1, 'a' )";
3020 r = run_query(hdb, 0, query);
3021 ok(r == ERROR_SUCCESS, "failed to add row\n");
3023 query = "INSERT INTO `MOO` ( `NOO`, `OOO` ) VALUES ( 2, 'b' )";
3024 r = run_query(hdb, 0, query);
3025 ok(r == ERROR_SUCCESS, "failed to add row\n");
3027 query = "INSERT INTO `MOO` ( `NOO`, `OOO` ) VALUES ( 3, 'c' )";
3028 r = run_query(hdb, 0, query);
3029 ok(r == ERROR_SUCCESS, "failed to add row\n");
3031 query = "CREATE TABLE `BINARY` ( `ID` SHORT NOT NULL, `BLOB` OBJECT PRIMARY KEY `ID`)";
3032 r = run_query(hdb, 0, query);
3033 ok(r == ERROR_SUCCESS, "failed to add table\n");
3035 hrec = MsiCreateRecord(2);
3036 r = MsiRecordSetInteger(hrec, 1, 2);
3037 ok(r == ERROR_SUCCESS, "failed to set integer\n");
3039 write_file("testdata.bin", "lamyon", 6);
3040 r = MsiRecordSetStream(hrec, 2, "testdata.bin");
3041 ok(r == ERROR_SUCCESS, "failed to set stream\n");
3043 query = "INSERT INTO `BINARY` ( `ID`, `BLOB` ) VALUES ( ?, ? )";
3044 r = run_query(hdb, hrec, query);
3045 ok(r == ERROR_SUCCESS, "failed to add row with blob\n");
3047 MsiCloseHandle(hrec);
3049 r = MsiDatabaseCommit( hdb );
3050 ok( r == ERROR_SUCCESS , "Failed to commit database\n" );
3052 MsiCloseHandle( hdb );
3053 DeleteFileA("testdata.bin");
3056 * Both these generate an equivalent transform,
3057 * but the first doesn't work in Wine yet
3058 * because MsiDatabaseGenerateTransform is unimplemented.
3061 generate_transform();
3063 generate_transform_manual();
3065 r = MsiOpenDatabase(msifile, MSIDBOPEN_DIRECT, &hdb );
3066 ok( r == ERROR_SUCCESS , "Failed to create database\n" );
3068 r = MsiDatabaseApplyTransform( hdb, mstfile, 0 );
3069 ok( r == ERROR_SUCCESS, "return code %d, should be ERROR_SUCCESS\n", r );
3071 MsiDatabaseCommit( hdb );
3073 /* check new values */
3075 query = "select `BAR`,`CAR` from `AAR` where `BAR` = 1 AND `CAR` = 'vw'";
3076 r = do_query(hdb, query, &hrec);
3077 ok(r == ERROR_SUCCESS, "select query failed\n");
3078 MsiCloseHandle(hrec);
3080 query = "select `BAR`,`CAR` from `AAR` where `BAR` = 2 AND `CAR` = 'bmw'";
3082 r = do_query(hdb, query, &hrec);
3083 ok(r == ERROR_SUCCESS, "select query failed\n");
3084 MsiCloseHandle(hrec);
3086 /* check updated values */
3088 query = "select `NOO`,`OOO` from `MOO` where `NOO` = 1 AND `OOO` = 'c'";
3089 r = do_query(hdb, query, &hrec);
3090 ok(r == ERROR_SUCCESS, "select query failed\n");
3091 MsiCloseHandle(hrec);
3093 /* check unchanged value */
3095 query = "select `NOO`,`OOO` from `MOO` where `NOO` = 2 AND `OOO` = 'b'";
3096 r = do_query(hdb, query, &hrec);
3097 ok(r == ERROR_SUCCESS, "select query failed\n");
3098 MsiCloseHandle(hrec);
3100 /* check deleted value */
3102 query = "select * from `MOO` where `NOO` = 3";
3103 r = do_query(hdb, query, &hrec);
3104 ok(r == ERROR_NO_MORE_ITEMS, "select query failed\n");
3105 if (hrec) MsiCloseHandle(hrec);
3107 /* check added stream */
3109 query = "select `BLOB` from `BINARY` where `ID` = 1";
3110 r = do_query(hdb, query, &hrec);
3111 ok(r == ERROR_SUCCESS, "select query failed\n");
3113 /* check the contents of the stream */
3115 r = MsiRecordReadStream( hrec, 1, buffer, &sz );
3116 ok(r == ERROR_SUCCESS, "read stream failed\n");
3117 ok(!memcmp(buffer, "naengmyon", 9), "stream data was wrong\n");
3118 ok(sz == 9, "stream data was wrong size\n");
3119 if (hrec) MsiCloseHandle(hrec);
3121 /* check the validity of the table with a deleted row */
3123 query = "select * from `MOO`";
3124 r = MsiDatabaseOpenView(hdb, query, &hview);
3125 ok(r == ERROR_SUCCESS, "open view failed\n");
3127 r = MsiViewExecute(hview, 0);
3128 ok(r == ERROR_SUCCESS, "view execute failed\n");
3130 r = MsiViewFetch(hview, &hrec);
3131 ok(r == ERROR_SUCCESS, "view fetch failed\n");
3133 r = MsiRecordGetInteger(hrec, 1);
3134 ok(r == 1, "Expected 1, got %d\n", r);
3137 r = MsiRecordGetString(hrec, 2, buffer, &sz);
3138 ok(r == ERROR_SUCCESS, "record get string failed\n");
3139 ok(!lstrcmpA(buffer, "c"), "Expected c, got %s\n", buffer);
3141 r = MsiRecordGetInteger(hrec, 3);
3142 ok(r == 0x80000000, "Expected 0x80000000, got %d\n", r);
3144 r = MsiRecordGetInteger(hrec, 4);
3145 ok(r == 5, "Expected 5, got %d\n", r);
3147 MsiCloseHandle(hrec);
3149 r = MsiViewFetch(hview, &hrec);
3150 ok(r == ERROR_SUCCESS, "view fetch failed\n");
3152 r = MsiRecordGetInteger(hrec, 1);
3153 ok(r == 2, "Expected 2, got %d\n", r);
3156 r = MsiRecordGetString(hrec, 2, buffer, &sz);
3157 ok(r == ERROR_SUCCESS, "record get string failed\n");
3158 ok(!lstrcmpA(buffer, "b"), "Expected b, got %s\n", buffer);
3160 r = MsiRecordGetInteger(hrec, 3);
3161 ok(r == 0x80000000, "Expected 0x80000000, got %d\n", r);
3163 r = MsiRecordGetInteger(hrec, 4);
3164 ok(r == 0x80000000, "Expected 0x80000000, got %d\n", r);
3166 MsiCloseHandle(hrec);
3168 r = MsiViewFetch(hview, &hrec);
3169 ok(r == ERROR_NO_MORE_ITEMS, "view fetch succeeded\n");
3171 MsiCloseHandle(hrec);
3172 MsiViewClose(hview);
3173 MsiCloseHandle(hview);
3175 /* check that the property was added */
3176 r = package_from_db(hdb, &hpkg);
3177 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
3179 skip("Not enough rights to perform tests\n");
3182 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3185 r = MsiGetProperty(hpkg, "prop", buffer, &sz);
3186 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3187 ok(!lstrcmp(buffer, "val"), "Expected val, got %s\n", buffer);
3189 MsiCloseHandle(hpkg);
3192 MsiCloseHandle(hdb);
3193 DeleteFile(msifile);
3194 DeleteFile(mstfile);
3199 const CHAR one[MAX_PATH];
3200 const CHAR two[MAX_PATH];
3203 struct join_res_4col
3205 const CHAR one[MAX_PATH];
3206 const CHAR two[MAX_PATH];
3207 const CHAR three[MAX_PATH];
3208 const CHAR four[MAX_PATH];
3211 struct join_res_uint
3221 static const struct join_res join_res_first[] =
3223 { "alveolar", "procerus" },
3224 { "septum", "procerus" },
3225 { "septum", "nasalis" },
3226 { "ramus", "nasalis" },
3227 { "malar", "mentalis" },
3230 static const struct join_res join_res_second[] =
3232 { "nasal", "septum" },
3233 { "mandible", "ramus" },
3236 static const struct join_res join_res_third[] =
3238 { "msvcp.dll", "abcdefgh" },
3239 { "msvcr.dll", "ijklmnop" },
3242 static const struct join_res join_res_fourth[] =
3244 { "msvcp.dll.01234", "single.dll.31415" },
3247 static const struct join_res join_res_fifth[] =
3249 { "malar", "procerus" },
3252 static const struct join_res join_res_sixth[] =
3254 { "malar", "procerus" },
3255 { "malar", "procerus" },
3256 { "malar", "nasalis" },
3257 { "malar", "nasalis" },
3258 { "malar", "nasalis" },
3259 { "malar", "mentalis" },
3262 static const struct join_res join_res_seventh[] =
3264 { "malar", "nasalis" },
3265 { "malar", "nasalis" },
3266 { "malar", "nasalis" },
3269 static const struct join_res_4col join_res_eighth[] =
3271 { "msvcp.dll", "msvcp.dll.01234", "msvcp.dll.01234", "abcdefgh" },
3272 { "msvcr.dll", "msvcr.dll.56789", "msvcp.dll.01234", "abcdefgh" },
3273 { "msvcp.dll", "msvcp.dll.01234", "msvcr.dll.56789", "ijklmnop" },
3274 { "msvcr.dll", "msvcr.dll.56789", "msvcr.dll.56789", "ijklmnop" },
3275 { "msvcp.dll", "msvcp.dll.01234", "single.dll.31415", "msvcp.dll" },
3276 { "msvcr.dll", "msvcr.dll.56789", "single.dll.31415", "msvcp.dll" },
3279 static const struct join_res_uint join_res_ninth[] =
3281 { 1, 2, 3, 4, 7, 8 },
3282 { 1, 2, 5, 6, 7, 8 },
3283 { 1, 2, 3, 4, 9, 10 },
3284 { 1, 2, 5, 6, 9, 10 },
3285 { 1, 2, 3, 4, 11, 12 },
3286 { 1, 2, 5, 6, 11, 12 },
3289 static void test_join(void)
3291 MSIHANDLE hdb, hview, hrec;
3299 ok( hdb, "failed to create db\n");
3301 r = create_component_table( hdb );
3302 ok( r == ERROR_SUCCESS, "cannot create Component table: %d\n", r );
3304 r = add_component_entry( hdb, "'zygomatic', 'malar', 'INSTALLDIR', 0, '', ''" );
3305 ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
3307 r = add_component_entry( hdb, "'maxilla', 'alveolar', 'INSTALLDIR', 0, '', ''" );
3308 ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
3310 r = add_component_entry( hdb, "'nasal', 'septum', 'INSTALLDIR', 0, '', ''" );
3311 ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
3313 r = add_component_entry( hdb, "'mandible', 'ramus', 'INSTALLDIR', 0, '', ''" );
3314 ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
3316 r = create_feature_components_table( hdb );
3317 ok( r == ERROR_SUCCESS, "cannot create FeatureComponents table: %d\n", r );
3319 r = add_feature_components_entry( hdb, "'procerus', 'maxilla'" );
3320 ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
3322 r = add_feature_components_entry( hdb, "'procerus', 'nasal'" );
3323 ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
3325 r = add_feature_components_entry( hdb, "'nasalis', 'nasal'" );
3326 ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
3328 r = add_feature_components_entry( hdb, "'nasalis', 'mandible'" );
3329 ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
3331 r = add_feature_components_entry( hdb, "'nasalis', 'notacomponent'" );
3332 ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
3334 r = add_feature_components_entry( hdb, "'mentalis', 'zygomatic'" );
3335 ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
3337 r = create_std_dlls_table( hdb );
3338 ok( r == ERROR_SUCCESS, "cannot create StdDlls table: %d\n", r );
3340 r = add_std_dlls_entry( hdb, "'msvcp.dll', 'msvcp.dll.01234'" );
3341 ok( r == ERROR_SUCCESS, "cannot add std dlls: %d\n", r );
3343 r = add_std_dlls_entry( hdb, "'msvcr.dll', 'msvcr.dll.56789'" );
3344 ok( r == ERROR_SUCCESS, "cannot add std dlls: %d\n", r );
3346 r = create_binary_table( hdb );
3347 ok( r == ERROR_SUCCESS, "cannot create Binary table: %d\n", r );
3349 r = add_binary_entry( hdb, "'msvcp.dll.01234', 'abcdefgh'" );
3350 ok( r == ERROR_SUCCESS, "cannot add binary: %d\n", r );
3352 r = add_binary_entry( hdb, "'msvcr.dll.56789', 'ijklmnop'" );
3353 ok( r == ERROR_SUCCESS, "cannot add binary: %d\n", r );
3355 r = add_binary_entry( hdb, "'single.dll.31415', 'msvcp.dll'" );
3356 ok( r == ERROR_SUCCESS, "cannot add binary: %d\n", r );
3358 query = "CREATE TABLE `One` (`A` SHORT, `B` SHORT PRIMARY KEY `A`)";
3359 r = run_query( hdb, 0, query);
3360 ok(r == ERROR_SUCCESS, "cannot create table: %d\n", r );
3362 query = "CREATE TABLE `Two` (`C` SHORT, `D` SHORT PRIMARY KEY `C`)";
3363 r = run_query( hdb, 0, query);
3364 ok(r == ERROR_SUCCESS, "cannot create table: %d\n", r );
3366 query = "CREATE TABLE `Three` (`E` SHORT, `F` SHORT PRIMARY KEY `E`)";
3367 r = run_query( hdb, 0, query);
3368 ok(r == ERROR_SUCCESS, "cannot create table: %d\n", r );
3370 query = "INSERT INTO `One` (`A`, `B`) VALUES (1, 2)";
3371 r = run_query( hdb, 0, query);
3372 ok(r == ERROR_SUCCESS, "cannot insert into table: %d\n", r );
3374 query = "INSERT INTO `Two` (`C`, `D`) VALUES (3, 4)";
3375 r = run_query( hdb, 0, query);
3376 ok(r == ERROR_SUCCESS, "cannot insert into table: %d\n", r );
3378 query = "INSERT INTO `Two` (`C`, `D`) VALUES (5, 6)";
3379 r = run_query( hdb, 0, query);
3380 ok(r == ERROR_SUCCESS, "cannot insert into table: %d\n", r );
3382 query = "INSERT INTO `Three` (`E`, `F`) VALUES (7, 8)";
3383 r = run_query( hdb, 0, query);
3384 ok(r == ERROR_SUCCESS, "cannot insert into table: %d\n", r );
3386 query = "INSERT INTO `Three` (`E`, `F`) VALUES (9, 10)";
3387 r = run_query( hdb, 0, query);
3388 ok(r == ERROR_SUCCESS, "cannot insert into table: %d\n", r );
3390 query = "INSERT INTO `Three` (`E`, `F`) VALUES (11, 12)";
3391 r = run_query( hdb, 0, query);
3392 ok(r == ERROR_SUCCESS, "cannot insert into table: %d\n", r );
3394 query = "CREATE TABLE `Four` (`G` SHORT, `H` SHORT PRIMARY KEY `G`)";
3395 r = run_query( hdb, 0, query);
3396 ok(r == ERROR_SUCCESS, "cannot create table: %d\n", r );
3398 query = "CREATE TABLE `Five` (`I` SHORT, `J` SHORT PRIMARY KEY `I`)";
3399 r = run_query( hdb, 0, query);
3400 ok(r == ERROR_SUCCESS, "cannot create table: %d\n", r );
3402 query = "INSERT INTO `Five` (`I`, `J`) VALUES (13, 14)";
3403 r = run_query( hdb, 0, query);
3404 ok(r == ERROR_SUCCESS, "cannot insert into table: %d\n", r );
3406 query = "INSERT INTO `Five` (`I`, `J`) VALUES (15, 16)";
3407 r = run_query( hdb, 0, query);
3408 ok(r == ERROR_SUCCESS, "cannot insert into table: %d\n", r );
3410 query = "SELECT `Component`.`ComponentId`, `FeatureComponents`.`Feature_` "
3411 "FROM `Component`, `FeatureComponents` "
3412 "WHERE `Component`.`Component` = `FeatureComponents`.`Component_` "
3413 "ORDER BY `Feature_`";
3414 r = MsiDatabaseOpenView(hdb, query, &hview);
3415 ok( r == ERROR_SUCCESS, "failed to open view: %d\n", r );
3417 r = MsiViewExecute(hview, 0);
3418 ok( r == ERROR_SUCCESS, "failed to execute view: %d\n", r );
3421 while ((r = MsiViewFetch(hview, &hrec)) == ERROR_SUCCESS)
3423 count = MsiRecordGetFieldCount( hrec );
3424 ok( count == 2, "Expected 2 record fields, got %d\n", count );
3427 r = MsiRecordGetString( hrec, 1, buf, &size );
3428 ok( r == ERROR_SUCCESS, "failed to get record string: %d\n", r );
3429 ok( !lstrcmp( buf, join_res_first[i].one ),
3430 "For (row %d, column 1) expected '%s', got %s\n", i, join_res_first[i].one, buf );
3433 r = MsiRecordGetString( hrec, 2, buf, &size );
3434 ok( r == ERROR_SUCCESS, "failed to get record string: %d\n", r );
3435 ok( !lstrcmp( buf, join_res_first[i].two ),
3436 "For (row %d, column 2) expected '%s', got %s\n", i, join_res_first[i].two, buf );
3439 MsiCloseHandle(hrec);
3442 ok( i == 5, "Expected 5 rows, got %d\n", i );
3443 ok( r == ERROR_NO_MORE_ITEMS, "expected no more items: %d\n", r );
3445 MsiViewClose(hview);
3446 MsiCloseHandle(hview);
3448 /* try a join without a WHERE condition */
3449 query = "SELECT `Component`.`ComponentId`, `FeatureComponents`.`Feature_` "
3450 "FROM `Component`, `FeatureComponents` ";
3451 r = MsiDatabaseOpenView(hdb, query, &hview);
3452 ok( r == ERROR_SUCCESS, "failed to open view: %d\n", r );
3454 r = MsiViewExecute(hview, 0);
3455 ok( r == ERROR_SUCCESS, "failed to execute view: %d\n", r );
3458 while ((r = MsiViewFetch(hview, &hrec)) == ERROR_SUCCESS)
3461 MsiCloseHandle(hrec);
3463 ok( i == 24, "Expected 24 rows, got %d\n", i );
3465 MsiViewClose(hview);
3466 MsiCloseHandle(hview);
3468 query = "SELECT DISTINCT Component, ComponentId FROM FeatureComponents, Component "
3469 "WHERE FeatureComponents.Component_=Component.Component "
3470 "AND (Feature_='nasalis') ORDER BY Feature_";
3471 r = MsiDatabaseOpenView(hdb, query, &hview);
3472 ok( r == ERROR_SUCCESS, "failed to open view: %d\n", r );
3474 r = MsiViewExecute(hview, 0);
3475 ok( r == ERROR_SUCCESS, "failed to execute view: %d\n", r );
3478 data_correct = TRUE;
3479 while ((r = MsiViewFetch(hview, &hrec)) == ERROR_SUCCESS)
3481 count = MsiRecordGetFieldCount( hrec );
3482 ok( count == 2, "Expected 2 record fields, got %d\n", count );
3485 r = MsiRecordGetString( hrec, 1, buf, &size );
3486 ok( r == ERROR_SUCCESS, "failed to get record string: %d\n", r );
3487 if( lstrcmp( buf, join_res_second[i].one ))
3488 data_correct = FALSE;
3491 r = MsiRecordGetString( hrec, 2, buf, &size );
3492 ok( r == ERROR_SUCCESS, "failed to get record string: %d\n", r );
3493 if( lstrcmp( buf, join_res_second[i].two ))
3494 data_correct = FALSE;
3497 MsiCloseHandle(hrec);
3500 ok( data_correct, "data returned in the wrong order\n");
3502 ok( i == 2, "Expected 2 rows, got %d\n", i );
3503 ok( r == ERROR_NO_MORE_ITEMS, "expected no more items: %d\n", r );
3505 MsiViewClose(hview);
3506 MsiCloseHandle(hview);
3508 query = "SELECT `StdDlls`.`File`, `Binary`.`Data` "
3509 "FROM `StdDlls`, `Binary` "
3510 "WHERE `StdDlls`.`Binary_` = `Binary`.`Name` "
3512 r = MsiDatabaseOpenView(hdb, query, &hview);
3513 ok( r == ERROR_SUCCESS, "failed to open view: %d\n", r );
3515 r = MsiViewExecute(hview, 0);
3516 ok( r == ERROR_SUCCESS, "failed to execute view: %d\n", r );
3519 data_correct = TRUE;
3520 while ((r = MsiViewFetch(hview, &hrec)) == ERROR_SUCCESS)
3522 count = MsiRecordGetFieldCount( hrec );
3523 ok( count == 2, "Expected 2 record fields, got %d\n", count );
3526 r = MsiRecordGetString( hrec, 1, buf, &size );
3527 ok( r == ERROR_SUCCESS, "failed to get record string: %d\n", r );
3528 if( lstrcmp( buf, join_res_third[i].one ) )
3529 data_correct = FALSE;
3532 r = MsiRecordGetString( hrec, 2, buf, &size );
3533 ok( r == ERROR_SUCCESS, "failed to get record string: %d\n", r );
3534 if( lstrcmp( buf, join_res_third[i].two ) )
3535 data_correct = FALSE;
3538 MsiCloseHandle(hrec);
3540 ok( data_correct, "data returned in the wrong order\n");
3542 ok( i == 2, "Expected 2 rows, got %d\n", i );
3544 ok( r == ERROR_NO_MORE_ITEMS, "expected no more items: %d\n", r );
3546 MsiViewClose(hview);
3547 MsiCloseHandle(hview);
3549 query = "SELECT `StdDlls`.`Binary_`, `Binary`.`Name` "
3550 "FROM `StdDlls`, `Binary` "
3551 "WHERE `StdDlls`.`File` = `Binary`.`Data` "
3553 r = MsiDatabaseOpenView(hdb, query, &hview);
3554 ok( r == ERROR_SUCCESS, "failed to open view: %d\n", r );
3556 r = MsiViewExecute(hview, 0);
3557 ok( r == ERROR_SUCCESS, "failed to execute view: %d\n", r );
3560 data_correct = TRUE;
3561 while ((r = MsiViewFetch(hview, &hrec)) == ERROR_SUCCESS)
3563 count = MsiRecordGetFieldCount( hrec );
3564 ok( count == 2, "Expected 2 record fields, got %d\n", count );
3567 r = MsiRecordGetString( hrec, 1, buf, &size );
3568 ok( r == ERROR_SUCCESS, "failed to get record string: %d\n", r );
3569 if( lstrcmp( buf, join_res_fourth[i].one ))
3570 data_correct = FALSE;
3573 r = MsiRecordGetString( hrec, 2, buf, &size );
3574 ok( r == ERROR_SUCCESS, "failed to get record string: %d\n", r );
3575 if( lstrcmp( buf, join_res_fourth[i].two ))
3576 data_correct = FALSE;
3579 MsiCloseHandle(hrec);
3581 ok( data_correct, "data returned in the wrong order\n");
3583 ok( i == 1, "Expected 1 rows, got %d\n", i );
3584 ok( r == ERROR_NO_MORE_ITEMS, "expected no more items: %d\n", r );
3586 MsiViewClose(hview);
3587 MsiCloseHandle(hview);
3589 query = "SELECT `Component`.`ComponentId`, `FeatureComponents`.`Feature_` "
3590 "FROM `Component`, `FeatureComponents` "
3591 "WHERE `Component`.`Component` = 'zygomatic' "
3592 "AND `FeatureComponents`.`Component_` = 'maxilla' "
3593 "ORDER BY `Feature_`";
3594 r = MsiDatabaseOpenView(hdb, query, &hview);
3595 ok( r == ERROR_SUCCESS, "failed to open view: %d\n", r );
3597 r = MsiViewExecute(hview, 0);
3598 ok( r == ERROR_SUCCESS, "failed to execute view: %d\n", r );
3601 data_correct = TRUE;
3602 while ((r = MsiViewFetch(hview, &hrec)) == ERROR_SUCCESS)
3604 count = MsiRecordGetFieldCount( hrec );
3605 ok( count == 2, "Expected 2 record fields, got %d\n", count );
3608 r = MsiRecordGetString( hrec, 1, buf, &size );
3609 ok( r == ERROR_SUCCESS, "failed to get record string: %d\n", r );
3610 if( lstrcmp( buf, join_res_fifth[i].one ))
3611 data_correct = FALSE;
3614 r = MsiRecordGetString( hrec, 2, buf, &size );
3615 ok( r == ERROR_SUCCESS, "failed to get record string: %d\n", r );
3616 if( lstrcmp( buf, join_res_fifth[i].two ))
3617 data_correct = FALSE;
3620 MsiCloseHandle(hrec);
3622 ok( data_correct, "data returned in the wrong order\n");
3624 ok( i == 1, "Expected 1 rows, got %d\n", i );
3625 ok( r == ERROR_NO_MORE_ITEMS, "expected no more items: %d\n", r );
3627 MsiViewClose(hview);
3628 MsiCloseHandle(hview);
3630 query = "SELECT `Component`.`ComponentId`, `FeatureComponents`.`Feature_` "
3631 "FROM `Component`, `FeatureComponents` "
3632 "WHERE `Component` = 'zygomatic' "
3633 "ORDER BY `Feature_`";
3634 r = MsiDatabaseOpenView(hdb, query, &hview);
3635 ok( r == ERROR_SUCCESS, "failed to open view: %d\n", r );
3637 r = MsiViewExecute(hview, 0);
3638 ok( r == ERROR_SUCCESS, "failed to execute view: %d\n", r );
3641 data_correct = TRUE;
3642 while ((r = MsiViewFetch(hview, &hrec)) == ERROR_SUCCESS)
3644 count = MsiRecordGetFieldCount( hrec );
3645 ok( count == 2, "Expected 2 record fields, got %d\n", count );
3648 r = MsiRecordGetString( hrec, 1, buf, &size );
3649 ok( r == ERROR_SUCCESS, "failed to get record string: %d\n", r );
3650 if( lstrcmp( buf, join_res_sixth[i].one ))
3651 data_correct = FALSE;
3654 r = MsiRecordGetString( hrec, 2, buf, &size );
3655 ok( r == ERROR_SUCCESS, "failed to get record string: %d\n", r );
3656 if( lstrcmp( buf, join_res_sixth[i].two ))
3657 data_correct = FALSE;
3660 MsiCloseHandle(hrec);
3662 ok( data_correct, "data returned in the wrong order\n");
3664 ok( i == 6, "Expected 6 rows, got %d\n", i );
3665 ok( r == ERROR_NO_MORE_ITEMS, "expected no more items: %d\n", r );
3667 MsiViewClose(hview);
3668 MsiCloseHandle(hview);
3670 query = "SELECT `Component`.`ComponentId`, `FeatureComponents`.`Feature_` "
3671 "FROM `Component`, `FeatureComponents` "
3672 "WHERE `Component` = 'zygomatic' "
3673 "AND `Feature_` = 'nasalis' "
3674 "ORDER BY `Feature_`";
3675 r = MsiDatabaseOpenView(hdb, query, &hview);
3676 ok( r == ERROR_SUCCESS, "failed to open view: %d\n", r );
3678 r = MsiViewExecute(hview, 0);
3679 ok( r == ERROR_SUCCESS, "failed to execute view: %d\n", r );
3682 data_correct = TRUE;
3683 while ((r = MsiViewFetch(hview, &hrec)) == ERROR_SUCCESS)
3685 count = MsiRecordGetFieldCount( hrec );
3686 ok( count == 2, "Expected 2 record fields, got %d\n", count );
3689 r = MsiRecordGetString( hrec, 1, buf, &size );
3690 ok( r == ERROR_SUCCESS, "failed to get record string: %d\n", r );
3691 if( lstrcmp( buf, join_res_seventh[i].one ))
3692 data_correct = FALSE;
3695 r = MsiRecordGetString( hrec, 2, buf, &size );
3696 ok( r == ERROR_SUCCESS, "failed to get record string: %d\n", r );
3697 if( lstrcmp( buf, join_res_seventh[i].two ))
3698 data_correct = FALSE;
3701 MsiCloseHandle(hrec);
3704 ok( data_correct, "data returned in the wrong order\n");
3705 ok( i == 3, "Expected 3 rows, got %d\n", i );
3706 ok( r == ERROR_NO_MORE_ITEMS, "expected no more items: %d\n", r );
3708 MsiViewClose(hview);
3709 MsiCloseHandle(hview);
3711 query = "SELECT `StdDlls`.`File`, `Binary`.`Data` "
3712 "FROM `StdDlls`, `Binary` ";
3713 r = MsiDatabaseOpenView(hdb, query, &hview);
3714 ok( r == ERROR_SUCCESS, "failed to open view: %d\n", r );
3716 r = MsiViewExecute(hview, 0);
3717 ok( r == ERROR_SUCCESS, "failed to execute view: %d\n", r );
3720 data_correct = TRUE;
3721 while ((r = MsiViewFetch(hview, &hrec)) == ERROR_SUCCESS)
3723 count = MsiRecordGetFieldCount( hrec );
3724 ok( count == 2, "Expected 2 record fields, got %d\n", count );
3727 r = MsiRecordGetString( hrec, 1, buf, &size );
3728 ok( r == ERROR_SUCCESS, "failed to get record string: %d\n", r );
3729 if( lstrcmp( buf, join_res_eighth[i].one ))
3730 data_correct = FALSE;
3733 r = MsiRecordGetString( hrec, 2, buf, &size );
3734 ok( r == ERROR_SUCCESS, "failed to get record string: %d\n", r );
3735 if( lstrcmp( buf, join_res_eighth[i].four ))
3736 data_correct = FALSE;
3739 MsiCloseHandle(hrec);
3742 ok( data_correct, "data returned in the wrong order\n");
3743 ok( i == 6, "Expected 6 rows, got %d\n", i );
3744 ok( r == ERROR_NO_MORE_ITEMS, "expected no more items: %d\n", r );
3746 MsiViewClose(hview);
3747 MsiCloseHandle(hview);
3749 query = "SELECT * FROM `StdDlls`, `Binary` ";
3750 r = MsiDatabaseOpenView(hdb, query, &hview);
3751 ok( r == ERROR_SUCCESS, "failed to open view: %d\n", r );
3753 r = MsiViewExecute(hview, 0);
3754 ok( r == ERROR_SUCCESS, "failed to execute view: %d\n", r );
3757 data_correct = TRUE;
3758 while ((r = MsiViewFetch(hview, &hrec)) == ERROR_SUCCESS)
3760 count = MsiRecordGetFieldCount( hrec );
3761 ok( count == 4, "Expected 4 record fields, got %d\n", count );
3764 r = MsiRecordGetString( hrec, 1, buf, &size );
3765 ok( r == ERROR_SUCCESS, "failed to get record string: %d\n", r );
3766 if( lstrcmp( buf, join_res_eighth[i].one ))
3767 data_correct = FALSE;
3770 r = MsiRecordGetString( hrec, 2, buf, &size );
3771 ok( r == ERROR_SUCCESS, "failed to get record string: %d\n", r );
3772 if( lstrcmp( buf, join_res_eighth[i].two ))
3773 data_correct = FALSE;
3776 r = MsiRecordGetString( hrec, 3, buf, &size );
3777 ok( r == ERROR_SUCCESS, "failed to get record string: %d\n", r );
3778 if( lstrcmp( buf, join_res_eighth[i].three ))
3779 data_correct = FALSE;
3782 r = MsiRecordGetString( hrec, 4, buf, &size );
3783 ok( r == ERROR_SUCCESS, "failed to get record string: %d\n", r );
3784 if( lstrcmp( buf, join_res_eighth[i].four ))
3785 data_correct = FALSE;
3788 MsiCloseHandle(hrec);
3790 ok( data_correct, "data returned in the wrong order\n");
3792 ok( i == 6, "Expected 6 rows, got %d\n", i );
3793 ok( r == ERROR_NO_MORE_ITEMS, "expected no more items: %d\n", r );
3795 MsiViewClose(hview);
3796 MsiCloseHandle(hview);
3798 query = "SELECT * FROM `One`, `Two`, `Three` ";
3799 r = MsiDatabaseOpenView(hdb, query, &hview);
3800 ok( r == ERROR_SUCCESS, "failed to open view: %d\n", r );
3802 r = MsiViewExecute(hview, 0);
3803 ok( r == ERROR_SUCCESS, "failed to execute view: %d\n", r );
3806 data_correct = TRUE;
3807 while ((r = MsiViewFetch(hview, &hrec)) == ERROR_SUCCESS)
3809 count = MsiRecordGetFieldCount( hrec );
3810 ok( count == 6, "Expected 6 record fields, got %d\n", count );
3812 r = MsiRecordGetInteger( hrec, 1 );
3813 if( r != join_res_ninth[i].one )
3814 data_correct = FALSE;
3816 r = MsiRecordGetInteger( hrec, 2 );
3817 if( r != join_res_ninth[i].two )
3818 data_correct = FALSE;
3820 r = MsiRecordGetInteger( hrec, 3 );
3821 if( r != join_res_ninth[i].three )
3822 data_correct = FALSE;
3824 r = MsiRecordGetInteger( hrec, 4 );
3825 if( r != join_res_ninth[i].four )
3826 data_correct = FALSE;
3828 r = MsiRecordGetInteger( hrec, 5 );
3829 if( r != join_res_ninth[i].five )
3830 data_correct = FALSE;
3832 r = MsiRecordGetInteger( hrec, 6);
3833 if( r != join_res_ninth[i].six )
3834 data_correct = FALSE;
3837 MsiCloseHandle(hrec);
3839 ok( data_correct, "data returned in the wrong order\n");
3841 ok( i == 6, "Expected 6 rows, got %d\n", i );
3842 ok( r == ERROR_NO_MORE_ITEMS, "expected no more items: %d\n", r );
3844 MsiViewClose(hview);
3845 MsiCloseHandle(hview);
3847 query = "SELECT * FROM `Four`, `Five`";
3848 r = MsiDatabaseOpenView(hdb, query, &hview);
3849 ok( r == ERROR_SUCCESS, "failed to open view: %d\n", r );
3851 r = MsiViewExecute(hview, 0);
3852 ok( r == ERROR_SUCCESS, "failed to execute view: %d\n", r );
3854 r = MsiViewFetch(hview, &hrec);
3855 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
3857 MsiViewClose(hview);
3858 MsiCloseHandle(hview);
3860 query = "SELECT * FROM `Nonexistent`, `One`";
3861 r = MsiDatabaseOpenView(hdb, query, &hview);
3862 ok( r == ERROR_BAD_QUERY_SYNTAX,
3863 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r );
3865 /* try updating a row in a join table */
3866 query = "SELECT `Component`.`ComponentId`, `FeatureComponents`.`Feature_` "
3867 "FROM `Component`, `FeatureComponents` "
3868 "WHERE `Component`.`Component` = `FeatureComponents`.`Component_` "
3869 "ORDER BY `Feature_`";
3870 r = MsiDatabaseOpenView(hdb, query, &hview);
3871 ok( r == ERROR_SUCCESS, "failed to open view: %d\n", r );
3873 r = MsiViewExecute(hview, 0);
3874 ok( r == ERROR_SUCCESS, "failed to execute view: %d\n", r );
3876 r = MsiViewFetch(hview, &hrec);
3877 ok( r == ERROR_SUCCESS, "failed to fetch view: %d\n", r );
3879 r = MsiRecordSetString( hrec, 1, "epicranius" );
3880 ok( r == ERROR_SUCCESS, "failed to set string: %d\n", r );
3882 r = MsiViewModify(hview, MSIMODIFY_UPDATE, hrec);
3883 ok( r == ERROR_SUCCESS, "failed to update row: %d\n", r );
3885 /* try another valid operation for joins */
3886 r = MsiViewModify(hview, MSIMODIFY_REFRESH, hrec);
3887 todo_wine ok( r == ERROR_SUCCESS, "failed to refresh row: %d\n", r );
3889 /* try an invalid operation for joins */
3890 r = MsiViewModify(hview, MSIMODIFY_DELETE, hrec);
3891 ok( r == ERROR_FUNCTION_FAILED, "unexpected result: %d\n", r );
3893 r = MsiRecordSetString( hrec, 2, "epicranius" );
3894 ok( r == ERROR_SUCCESS, "failed to set string: %d\n", r );
3896 /* primary key cannot be updated */
3897 r = MsiViewModify(hview, MSIMODIFY_UPDATE, hrec);
3898 todo_wine ok( r == ERROR_FUNCTION_FAILED, "failed to update row: %d\n", r );
3900 MsiCloseHandle(hrec);
3901 MsiViewClose(hview);
3902 MsiCloseHandle(hview);
3904 r = MsiDatabaseOpenView(hdb, query, &hview);
3905 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
3907 r = MsiViewExecute(hview, 0);
3908 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n");
3910 r = MsiViewFetch(hview, &hrec);
3911 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n");
3914 r = MsiRecordGetString( hrec, 1, buf, &size );
3915 ok( r == ERROR_SUCCESS, "failed to get record string: %d\n", r );
3916 ok( !lstrcmp( buf, "epicranius" ), "expected 'epicranius', got %s\n", buf );
3918 MsiCloseHandle(hrec);
3919 MsiViewClose(hview);
3920 MsiCloseHandle(hview);
3922 MsiCloseHandle(hdb);
3923 DeleteFile(msifile);
3926 static void test_temporary_table(void)
3929 MSIHANDLE hdb = 0, view = 0, rec;
3935 cond = MsiDatabaseIsTablePersistent(0, NULL);
3936 ok( cond == MSICONDITION_ERROR, "wrong return condition\n");
3939 ok( hdb, "failed to create db\n");
3941 cond = MsiDatabaseIsTablePersistent(hdb, NULL);
3942 ok( cond == MSICONDITION_ERROR, "wrong return condition\n");
3944 cond = MsiDatabaseIsTablePersistent(hdb, "_Tables");
3945 ok( cond == MSICONDITION_NONE, "wrong return condition\n");
3947 cond = MsiDatabaseIsTablePersistent(hdb, "_Columns");
3948 ok( cond == MSICONDITION_NONE, "wrong return condition\n");
3950 cond = MsiDatabaseIsTablePersistent(hdb, "_Storages");
3951 ok( cond == MSICONDITION_NONE, "wrong return condition\n");
3953 cond = MsiDatabaseIsTablePersistent(hdb, "_Streams");
3954 ok( cond == MSICONDITION_NONE, "wrong return condition\n");
3956 query = "CREATE TABLE `P` ( `B` SHORT NOT NULL, `C` CHAR(255) PRIMARY KEY `C`)";
3957 r = run_query(hdb, 0, query);
3958 ok(r == ERROR_SUCCESS, "failed to add table\n");
3960 cond = MsiDatabaseIsTablePersistent(hdb, "P");
3961 ok( cond == MSICONDITION_TRUE, "wrong return condition\n");
3963 query = "CREATE TABLE `P2` ( `B` SHORT NOT NULL, `C` CHAR(255) PRIMARY KEY `C`) HOLD";
3964 r = run_query(hdb, 0, query);
3965 ok(r == ERROR_SUCCESS, "failed to add table\n");
3967 cond = MsiDatabaseIsTablePersistent(hdb, "P2");
3968 ok( cond == MSICONDITION_TRUE, "wrong return condition\n");
3970 query = "CREATE TABLE `T` ( `B` SHORT NOT NULL TEMPORARY, `C` CHAR(255) TEMPORARY PRIMARY KEY `C`) HOLD";
3971 r = run_query(hdb, 0, query);
3972 ok(r == ERROR_SUCCESS, "failed to add table\n");
3974 cond = MsiDatabaseIsTablePersistent(hdb, "T");
3975 ok( cond == MSICONDITION_FALSE, "wrong return condition\n");
3977 query = "CREATE TABLE `T2` ( `B` SHORT NOT NULL TEMPORARY, `C` CHAR(255) TEMPORARY PRIMARY KEY `C`)";
3978 r = run_query(hdb, 0, query);
3979 ok(r == ERROR_SUCCESS, "failed to add table\n");
3981 query = "SELECT * FROM `T2`";
3982 r = MsiDatabaseOpenView(hdb, query, &view);
3983 ok(r == ERROR_BAD_QUERY_SYNTAX,
3984 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
3986 cond = MsiDatabaseIsTablePersistent(hdb, "T2");
3987 ok( cond == MSICONDITION_NONE, "wrong return condition\n");
3989 query = "CREATE TABLE `T3` ( `B` SHORT NOT NULL TEMPORARY, `C` CHAR(255) PRIMARY KEY `C`)";
3990 r = run_query(hdb, 0, query);
3991 ok(r == ERROR_SUCCESS, "failed to add table\n");
3993 cond = MsiDatabaseIsTablePersistent(hdb, "T3");
3994 ok( cond == MSICONDITION_TRUE, "wrong return condition\n");
3996 query = "CREATE TABLE `T4` ( `B` SHORT NOT NULL, `C` CHAR(255) TEMPORARY PRIMARY KEY `C`)";
3997 r = run_query(hdb, 0, query);
3998 ok(r == ERROR_FUNCTION_FAILED, "failed to add table\n");
4000 cond = MsiDatabaseIsTablePersistent(hdb, "T4");
4001 ok( cond == MSICONDITION_NONE, "wrong return condition\n");
4003 query = "CREATE TABLE `T5` ( `B` SHORT NOT NULL TEMP, `C` CHAR(255) TEMP PRIMARY KEY `C`) HOLD";
4004 r = run_query(hdb, 0, query);
4005 ok(r == ERROR_BAD_QUERY_SYNTAX, "failed to add table\n");
4007 query = "select * from `T`";
4008 r = MsiDatabaseOpenView(hdb, query, &view);
4009 ok(r == ERROR_SUCCESS, "failed to query table\n");
4010 r = MsiViewGetColumnInfo(view, MSICOLINFO_TYPES, &rec);
4011 ok(r == ERROR_SUCCESS, "failed to get column info\n");
4014 r = MsiRecordGetString(rec, 1, buf, &sz);
4015 ok(r == ERROR_SUCCESS, "failed to get string\n");
4016 ok( 0 == strcmp("G255", buf), "wrong column type\n");
4019 r = MsiRecordGetString(rec, 2, buf, &sz);
4020 ok(r == ERROR_SUCCESS, "failed to get string\n");
4021 ok( 0 == strcmp("j2", buf), "wrong column type\n");
4023 MsiCloseHandle( rec );
4024 MsiViewClose( view );
4025 MsiCloseHandle( view );
4027 /* query the table data */
4029 r = do_query(hdb, "select * from `_Tables` where `Name` = 'T'", &rec);
4030 ok( r == ERROR_SUCCESS, "temporary table exists in _Tables\n");
4031 MsiCloseHandle( rec );
4033 /* query the column data */
4035 r = do_query(hdb, "select * from `_Columns` where `Table` = 'T' AND `Name` = 'B'", &rec);
4036 ok( r == ERROR_NO_MORE_ITEMS, "temporary table exists in _Columns\n");
4037 if (rec) MsiCloseHandle( rec );
4039 r = do_query(hdb, "select * from `_Columns` where `Table` = 'T' AND `Name` = 'C'", &rec);
4040 ok( r == ERROR_NO_MORE_ITEMS, "temporary table exists in _Columns\n");
4041 if (rec) MsiCloseHandle( rec );
4043 MsiCloseHandle( hdb );
4045 DeleteFile(msifile);
4048 static void test_alter(void)
4056 ok( hdb, "failed to create db\n");
4058 query = "CREATE TABLE `T` ( `B` SHORT NOT NULL TEMPORARY, `C` CHAR(255) TEMPORARY PRIMARY KEY `C`) HOLD";
4059 r = run_query(hdb, 0, query);
4060 ok(r == ERROR_SUCCESS, "failed to add table\n");
4062 cond = MsiDatabaseIsTablePersistent(hdb, "T");
4063 ok( cond == MSICONDITION_FALSE, "wrong return condition\n");
4065 query = "ALTER TABLE `T` HOLD";
4066 r = run_query(hdb, 0, query);
4067 ok(r == ERROR_SUCCESS, "failed to hold table %d\n", r);
4069 query = "ALTER TABLE `T` FREE";
4070 r = run_query(hdb, 0, query);
4071 ok(r == ERROR_SUCCESS, "failed to free table\n");
4073 query = "ALTER TABLE `T` FREE";
4074 r = run_query(hdb, 0, query);
4075 ok(r == ERROR_SUCCESS, "failed to free table\n");
4077 query = "ALTER TABLE `T` FREE";
4078 r = run_query(hdb, 0, query);
4079 ok(r == ERROR_BAD_QUERY_SYNTAX, "failed to free table\n");
4081 query = "ALTER TABLE `T` HOLD";
4082 r = run_query(hdb, 0, query);
4083 ok(r == ERROR_BAD_QUERY_SYNTAX, "failed to hold table %d\n", r);
4085 /* table T is removed */
4086 query = "SELECT * FROM `T`";
4087 r = run_query(hdb, 0, query);
4088 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
4090 /* create the table again */
4091 query = "CREATE TABLE `U` ( `A` INTEGER, `B` INTEGER PRIMARY KEY `B`)";
4092 r = run_query(hdb, 0, query);
4093 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4095 /* up the ref count */
4096 query = "ALTER TABLE `U` HOLD";
4097 r = run_query(hdb, 0, query);
4098 ok(r == ERROR_SUCCESS, "failed to free table\n");
4100 /* add column, no data type */
4101 query = "ALTER TABLE `U` ADD `C`";
4102 r = run_query(hdb, 0, query);
4103 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
4105 query = "ALTER TABLE `U` ADD `C` INTEGER";
4106 r = run_query(hdb, 0, query);
4107 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4109 /* add column C again */
4110 query = "ALTER TABLE `U` ADD `C` INTEGER";
4111 r = run_query(hdb, 0, query);
4112 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
4114 query = "ALTER TABLE `U` ADD `D` INTEGER TEMPORARY";
4115 r = run_query(hdb, 0, query);
4116 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4118 query = "INSERT INTO `U` ( `A`, `B`, `C`, `D` ) VALUES ( 1, 2, 3, 4 )";
4119 r = run_query(hdb, 0, query);
4120 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4122 query = "ALTER TABLE `U` ADD `D` INTEGER TEMPORARY HOLD";
4123 r = run_query(hdb, 0, query);
4124 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
4126 query = "INSERT INTO `U` ( `A`, `B`, `C`, `D` ) VALUES ( 5, 6, 7, 8 )";
4127 r = run_query(hdb, 0, query);
4128 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4130 query = "SELECT * FROM `U` WHERE `D` = 8";
4131 r = run_query(hdb, 0, query);
4132 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4134 query = "ALTER TABLE `U` ADD `D` INTEGER TEMPORARY FREE";
4135 r = run_query(hdb, 0, query);
4136 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
4138 query = "ALTER COLUMN `D` FREE";
4139 r = run_query(hdb, 0, query);
4140 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
4142 /* drop the ref count */
4143 query = "ALTER TABLE `U` FREE";
4144 r = run_query(hdb, 0, query);
4145 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4147 /* table is not empty */
4148 query = "SELECT * FROM `U`";
4149 r = run_query(hdb, 0, query);
4150 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4152 /* column D is removed */
4153 query = "SELECT * FROM `U` WHERE `D` = 8";
4154 r = run_query(hdb, 0, query);
4155 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
4157 query = "INSERT INTO `U` ( `A`, `B`, `C`, `D` ) VALUES ( 9, 10, 11, 12 )";
4158 r = run_query(hdb, 0, query);
4159 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
4161 /* add the column again */
4162 query = "ALTER TABLE `U` ADD `E` INTEGER TEMPORARY HOLD";
4163 r = run_query(hdb, 0, query);
4164 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4166 /* up the ref count */
4167 query = "ALTER TABLE `U` HOLD";
4168 r = run_query(hdb, 0, query);
4169 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4171 query = "INSERT INTO `U` ( `A`, `B`, `C`, `E` ) VALUES ( 13, 14, 15, 16 )";
4172 r = run_query(hdb, 0, query);
4173 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4175 query = "SELECT * FROM `U` WHERE `E` = 16";
4176 r = run_query(hdb, 0, query);
4177 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4179 /* drop the ref count */
4180 query = "ALTER TABLE `U` FREE";
4181 r = run_query(hdb, 0, query);
4182 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4184 query = "INSERT INTO `U` ( `A`, `B`, `C`, `E` ) VALUES ( 17, 18, 19, 20 )";
4185 r = run_query(hdb, 0, query);
4186 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4188 query = "SELECT * FROM `U` WHERE `E` = 20";
4189 r = run_query(hdb, 0, query);
4190 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4192 /* drop the ref count */
4193 query = "ALTER TABLE `U` FREE";
4194 r = run_query(hdb, 0, query);
4195 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4197 /* table still exists */
4198 query = "SELECT * FROM `U`";
4199 r = run_query(hdb, 0, query);
4200 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4202 /* col E is removed */
4203 query = "SELECT * FROM `U` WHERE `E` = 20";
4204 r = run_query(hdb, 0, query);
4205 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
4207 query = "INSERT INTO `U` ( `A`, `B`, `C`, `E` ) VALUES ( 20, 21, 22, 23 )";
4208 r = run_query(hdb, 0, query);
4209 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
4211 /* drop the ref count once more */
4212 query = "ALTER TABLE `U` FREE";
4213 r = run_query(hdb, 0, query);
4214 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4216 /* table still exists */
4217 query = "SELECT * FROM `U`";
4218 r = run_query(hdb, 0, query);
4219 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4221 MsiCloseHandle( hdb );
4222 DeleteFile(msifile);
4225 static void test_integers(void)
4227 MSIHANDLE hdb = 0, view = 0, rec = 0;
4232 /* just MsiOpenDatabase should not create a file */
4233 r = MsiOpenDatabase(msifile, MSIDBOPEN_CREATE, &hdb);
4234 ok(r == ERROR_SUCCESS, "MsiOpenDatabase failed\n");
4236 /* create a table */
4237 query = "CREATE TABLE `integers` ( "
4238 "`one` SHORT, `two` INT, `three` INTEGER, `four` LONG, "
4239 "`five` SHORT NOT NULL, `six` INT NOT NULL, "
4240 "`seven` INTEGER NOT NULL, `eight` LONG NOT NULL "
4241 "PRIMARY KEY `one`)";
4242 r = MsiDatabaseOpenView(hdb, query, &view);
4243 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
4244 r = MsiViewExecute(view, 0);
4245 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n");
4246 r = MsiViewClose(view);
4247 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n");
4248 r = MsiCloseHandle(view);
4249 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
4251 query = "SELECT * FROM `integers`";
4252 r = MsiDatabaseOpenView(hdb, query, &view);
4253 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4255 r = MsiViewGetColumnInfo(view, MSICOLINFO_NAMES, &rec);
4256 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4257 count = MsiRecordGetFieldCount(rec);
4258 ok(count == 8, "Expected 8, got %d\n", count);
4259 ok(check_record(rec, 1, "one"), "Expected one\n");
4260 ok(check_record(rec, 2, "two"), "Expected two\n");
4261 ok(check_record(rec, 3, "three"), "Expected three\n");
4262 ok(check_record(rec, 4, "four"), "Expected four\n");
4263 ok(check_record(rec, 5, "five"), "Expected five\n");
4264 ok(check_record(rec, 6, "six"), "Expected six\n");
4265 ok(check_record(rec, 7, "seven"), "Expected seven\n");
4266 ok(check_record(rec, 8, "eight"), "Expected eight\n");
4267 MsiCloseHandle(rec);
4269 r = MsiViewGetColumnInfo(view, MSICOLINFO_TYPES, &rec);
4270 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4271 count = MsiRecordGetFieldCount(rec);
4272 ok(count == 8, "Expected 8, got %d\n", count);
4273 ok(check_record(rec, 1, "I2"), "Expected I2\n");
4274 ok(check_record(rec, 2, "I2"), "Expected I2\n");
4275 ok(check_record(rec, 3, "I2"), "Expected I2\n");
4276 ok(check_record(rec, 4, "I4"), "Expected I4\n");
4277 ok(check_record(rec, 5, "i2"), "Expected i2\n");
4278 ok(check_record(rec, 6, "i2"), "Expected i2\n");
4279 ok(check_record(rec, 7, "i2"), "Expected i2\n");
4280 ok(check_record(rec, 8, "i4"), "Expected i4\n");
4281 MsiCloseHandle(rec);
4284 MsiCloseHandle(view);
4286 /* insert values into it, NULL where NOT NULL is specified */
4287 query = "INSERT INTO `integers` ( `one`, `two`, `three`, `four`, `five`, `six`, `seven`, `eight` )"
4288 "VALUES('', '', '', '', '', '', '', '')";
4289 r = MsiDatabaseOpenView(hdb, query, &view);
4290 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4291 r = MsiViewExecute(view, 0);
4292 ok(r == ERROR_FUNCTION_FAILED, "Expected ERROR_FUNCTION_FAILED, got %d\n", r);
4295 MsiCloseHandle(view);
4297 query = "SELECT * FROM `integers`";
4298 r = do_query(hdb, query, &rec);
4299 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
4301 r = MsiRecordGetFieldCount(rec);
4302 ok(r == -1, "record count wrong: %d\n", r);
4304 MsiCloseHandle(rec);
4306 /* insert legitimate values into it */
4307 query = "INSERT INTO `integers` ( `one`, `two`, `three`, `four`, `five`, `six`, `seven`, `eight` )"
4308 "VALUES('', '2', '', '4', '5', '6', '7', '8')";
4309 r = MsiDatabaseOpenView(hdb, query, &view);
4310 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4311 r = MsiViewExecute(view, 0);
4312 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4314 query = "SELECT * FROM `integers`";
4315 r = do_query(hdb, query, &rec);
4316 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4318 r = MsiRecordGetFieldCount(rec);
4319 ok(r == 8, "record count wrong: %d\n", r);
4321 i = MsiRecordGetInteger(rec, 1);
4322 ok(i == MSI_NULL_INTEGER, "Expected MSI_NULL_INTEGER, got %d\n", i);
4323 i = MsiRecordGetInteger(rec, 3);
4324 ok(i == MSI_NULL_INTEGER, "Expected MSI_NULL_INTEGER, got %d\n", i);
4325 i = MsiRecordGetInteger(rec, 2);
4326 ok(i == 2, "Expected 2, got %d\n", i);
4327 i = MsiRecordGetInteger(rec, 4);
4328 ok(i == 4, "Expected 4, got %d\n", i);
4329 i = MsiRecordGetInteger(rec, 5);
4330 ok(i == 5, "Expected 5, got %d\n", i);
4331 i = MsiRecordGetInteger(rec, 6);
4332 ok(i == 6, "Expected 6, got %d\n", i);
4333 i = MsiRecordGetInteger(rec, 7);
4334 ok(i == 7, "Expected 7, got %d\n", i);
4335 i = MsiRecordGetInteger(rec, 8);
4336 ok(i == 8, "Expected 8, got %d\n", i);
4338 MsiCloseHandle(rec);
4340 MsiCloseHandle(view);
4342 r = MsiDatabaseCommit(hdb);
4343 ok(r == ERROR_SUCCESS, "MsiDatabaseCommit failed\n");
4345 r = MsiCloseHandle(hdb);
4346 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
4348 r = DeleteFile(msifile);
4349 ok(r == TRUE, "file didn't exist after commit\n");
4352 static void test_update(void)
4354 MSIHANDLE hdb = 0, view = 0, rec = 0;
4355 CHAR result[MAX_PATH];
4360 /* just MsiOpenDatabase should not create a file */
4361 r = MsiOpenDatabase(msifile, MSIDBOPEN_CREATE, &hdb);
4362 ok(r == ERROR_SUCCESS, "MsiOpenDatabase failed\n");
4364 /* create the Control table */
4365 query = "CREATE TABLE `Control` ( "
4366 "`Dialog_` CHAR(72) NOT NULL, `Control` CHAR(50) NOT NULL, `Type` SHORT NOT NULL, "
4367 "`X` SHORT NOT NULL, `Y` SHORT NOT NULL, `Width` SHORT NOT NULL, `Height` SHORT NOT NULL,"
4368 "`Attributes` LONG, `Property` CHAR(50), `Text` CHAR(0) LOCALIZABLE, "
4369 "`Control_Next` CHAR(50), `Help` CHAR(50) LOCALIZABLE PRIMARY KEY `Dialog_`, `Control`)";
4370 r = MsiDatabaseOpenView(hdb, query, &view);
4371 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
4372 r = MsiViewExecute(view, 0);
4373 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n");
4374 r = MsiViewClose(view);
4375 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n");
4376 r = MsiCloseHandle(view);
4377 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
4380 query = "INSERT INTO `Control` ( "
4381 "`Dialog_`, `Control`, `Type`, `X`, `Y`, `Width`, `Height`, "
4382 "`Property`, `Text`, `Control_Next`, `Help` )"
4383 "VALUES('ErrorDialog', 'ErrorText', '1', '5', '5', '5', '5', '', '', '', '')";
4384 r = MsiDatabaseOpenView(hdb, query, &view);
4385 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4386 r = MsiViewExecute(view, 0);
4387 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4388 r = MsiViewClose(view);
4389 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n");
4390 r = MsiCloseHandle(view);
4391 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
4393 /* add a second control */
4394 query = "INSERT INTO `Control` ( "
4395 "`Dialog_`, `Control`, `Type`, `X`, `Y`, `Width`, `Height`, "
4396 "`Property`, `Text`, `Control_Next`, `Help` )"
4397 "VALUES('ErrorDialog', 'Button', '1', '5', '5', '5', '5', '', '', '', '')";
4398 r = MsiDatabaseOpenView(hdb, query, &view);
4399 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4400 r = MsiViewExecute(view, 0);
4401 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4402 r = MsiViewClose(view);
4403 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n");
4404 r = MsiCloseHandle(view);
4405 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
4407 /* add a third control */
4408 query = "INSERT INTO `Control` ( "
4409 "`Dialog_`, `Control`, `Type`, `X`, `Y`, `Width`, `Height`, "
4410 "`Property`, `Text`, `Control_Next`, `Help` )"
4411 "VALUES('AnotherDialog', 'ErrorText', '1', '5', '5', '5', '5', '', '', '', '')";
4412 r = MsiDatabaseOpenView(hdb, query, &view);
4413 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4414 r = MsiViewExecute(view, 0);
4415 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4416 r = MsiViewClose(view);
4417 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n");
4418 r = MsiCloseHandle(view);
4419 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
4422 query = "UPDATE `NotATable` SET `Text` = 'this is text' WHERE `Dialog_` = 'ErrorDialog'";
4423 r = MsiDatabaseOpenView(hdb, query, &view);
4424 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
4426 /* bad set column */
4427 query = "UPDATE `Control` SET `NotAColumn` = 'this is text' WHERE `Dialog_` = 'ErrorDialog'";
4428 r = MsiDatabaseOpenView(hdb, query, &view);
4429 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
4431 /* bad where condition */
4432 query = "UPDATE `Control` SET `Text` = 'this is text' WHERE `NotAColumn` = 'ErrorDialog'";
4433 r = MsiDatabaseOpenView(hdb, query, &view);
4434 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
4436 /* just the dialog_ specified */
4437 query = "UPDATE `Control` SET `Text` = 'this is text' WHERE `Dialog_` = 'ErrorDialog'";
4438 r = MsiDatabaseOpenView(hdb, query, &view);
4439 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4440 r = MsiViewExecute(view, 0);
4441 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4442 r = MsiViewClose(view);
4443 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n");
4444 r = MsiCloseHandle(view);
4445 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
4447 /* check the modified text */
4448 query = "SELECT `Text` FROM `Control` WHERE `Control` = 'ErrorText'";
4449 r = MsiDatabaseOpenView(hdb, query, &view);
4450 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4451 r = MsiViewExecute(view, 0);
4452 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4454 r = MsiViewFetch(view, &rec);
4455 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4458 r = MsiRecordGetString(rec, 1, result, &size);
4459 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4460 ok(!lstrcmp(result, "this is text"), "Expected `this is text`, got %s\n", result);
4462 MsiCloseHandle(rec);
4464 r = MsiViewFetch(view, &rec);
4465 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4468 r = MsiRecordGetString(rec, 1, result, &size);
4469 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4470 ok(!lstrlen(result), "Expected an empty string, got %s\n", result);
4472 MsiCloseHandle(rec);
4474 r = MsiViewFetch(view, &rec);
4475 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
4477 r = MsiViewClose(view);
4478 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n");
4479 r = MsiCloseHandle(view);
4480 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
4482 /* dialog_ and control specified */
4483 query = "UPDATE `Control` SET `Text` = 'this is text' WHERE `Dialog_` = 'ErrorDialog' AND `Control` = 'ErrorText'";
4484 r = MsiDatabaseOpenView(hdb, query, &view);
4485 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4486 r = MsiViewExecute(view, 0);
4487 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4488 r = MsiViewClose(view);
4489 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n");
4490 r = MsiCloseHandle(view);
4491 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
4493 /* check the modified text */
4494 query = "SELECT `Text` FROM `Control` WHERE `Control` = 'ErrorText'";
4495 r = MsiDatabaseOpenView(hdb, query, &view);
4496 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4497 r = MsiViewExecute(view, 0);
4498 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4500 r = MsiViewFetch(view, &rec);
4501 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4504 r = MsiRecordGetString(rec, 1, result, &size);
4505 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4506 ok(!lstrcmp(result, "this is text"), "Expected `this is text`, got %s\n", result);
4508 MsiCloseHandle(rec);
4510 r = MsiViewFetch(view, &rec);
4511 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4514 r = MsiRecordGetString(rec, 1, result, &size);
4515 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4516 ok(!lstrlen(result), "Expected an empty string, got %s\n", result);
4518 MsiCloseHandle(rec);
4520 r = MsiViewFetch(view, &rec);
4521 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
4523 r = MsiViewClose(view);
4524 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n");
4525 r = MsiCloseHandle(view);
4526 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
4528 /* no where condition */
4529 query = "UPDATE `Control` SET `Text` = 'this is text'";
4530 r = MsiDatabaseOpenView(hdb, query, &view);
4531 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4532 r = MsiViewExecute(view, 0);
4533 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4534 r = MsiViewClose(view);
4535 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n");
4536 r = MsiCloseHandle(view);
4537 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
4539 /* check the modified text */
4540 query = "SELECT `Text` FROM `Control`";
4541 r = MsiDatabaseOpenView(hdb, query, &view);
4542 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4543 r = MsiViewExecute(view, 0);
4544 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4546 r = MsiViewFetch(view, &rec);
4547 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4550 r = MsiRecordGetString(rec, 1, result, &size);
4551 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4552 ok(!lstrcmp(result, "this is text"), "Expected `this is text`, got %s\n", result);
4554 MsiCloseHandle(rec);
4556 r = MsiViewFetch(view, &rec);
4557 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4560 r = MsiRecordGetString(rec, 1, result, &size);
4561 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4562 ok(!lstrcmp(result, "this is text"), "Expected `this is text`, got %s\n", result);
4564 MsiCloseHandle(rec);
4566 r = MsiViewFetch(view, &rec);
4567 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4570 r = MsiRecordGetString(rec, 1, result, &size);
4571 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4572 ok(!lstrcmp(result, "this is text"), "Expected `this is text`, got %s\n", result);
4574 MsiCloseHandle(rec);
4576 r = MsiViewFetch(view, &rec);
4577 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
4579 r = MsiViewClose(view);
4580 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n");
4581 r = MsiCloseHandle(view);
4582 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
4584 query = "CREATE TABLE `Apple` ( `Banana` CHAR(72) NOT NULL, "
4585 "`Orange` CHAR(72), `Pear` INT PRIMARY KEY `Banana`)";
4586 r = run_query(hdb, 0, query);
4587 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4589 query = "INSERT INTO `Apple` ( `Banana`, `Orange`, `Pear` )"
4590 "VALUES('one', 'two', 3)";
4591 r = run_query(hdb, 0, query);
4592 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4594 query = "INSERT INTO `Apple` ( `Banana`, `Orange`, `Pear` )"
4595 "VALUES('three', 'four', 5)";
4596 r = run_query(hdb, 0, query);
4597 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4599 query = "INSERT INTO `Apple` ( `Banana`, `Orange`, `Pear` )"
4600 "VALUES('six', 'two', 7)";
4601 r = run_query(hdb, 0, query);
4602 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4604 rec = MsiCreateRecord(2);
4605 MsiRecordSetInteger(rec, 1, 8);
4606 MsiRecordSetString(rec, 2, "two");
4608 query = "UPDATE `Apple` SET `Pear` = ? WHERE `Orange` = ?";
4609 r = run_query(hdb, rec, query);
4610 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4612 MsiCloseHandle(rec);
4614 query = "SELECT `Pear` FROM `Apple` ORDER BY `Orange`";
4615 r = MsiDatabaseOpenView(hdb, query, &view);
4616 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4617 r = MsiViewExecute(view, 0);
4618 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4620 r = MsiViewFetch(view, &rec);
4621 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4623 r = MsiRecordGetInteger(rec, 1);
4624 ok(r == 8, "Expected 8, got %d\n", r);
4626 MsiCloseHandle(rec);
4628 r = MsiViewFetch(view, &rec);
4629 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4631 r = MsiRecordGetInteger(rec, 1);
4632 ok(r == 8, "Expected 8, got %d\n", r);
4634 MsiCloseHandle(rec);
4636 r = MsiViewFetch(view, &rec);
4637 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4639 r = MsiRecordGetInteger(rec, 1);
4640 ok(r == 5, "Expected 5, got %d\n", r);
4642 MsiCloseHandle(rec);
4644 r = MsiViewFetch(view, &rec);
4645 ok(r == ERROR_NO_MORE_ITEMS, "Expectd ERROR_NO_MORE_ITEMS, got %d\n", r);
4648 MsiCloseHandle(view);
4650 r = MsiDatabaseCommit(hdb);
4651 ok(r == ERROR_SUCCESS, "MsiDatabaseCommit failed\n");
4652 r = MsiCloseHandle(hdb);
4653 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
4655 DeleteFile(msifile);
4658 static void test_special_tables(void)
4664 r = MsiOpenDatabase(msifile, MSIDBOPEN_CREATE, &hdb);
4665 ok(r == ERROR_SUCCESS, "MsiOpenDatabase failed\n");
4667 query = "CREATE TABLE `_Properties` ( "
4668 "`foo` INT NOT NULL, `bar` INT LOCALIZABLE PRIMARY KEY `foo`)";
4669 r = run_query(hdb, 0, query);
4670 ok(r == ERROR_SUCCESS, "failed to create table\n");
4672 query = "CREATE TABLE `_Storages` ( "
4673 "`foo` INT NOT NULL, `bar` INT LOCALIZABLE PRIMARY KEY `foo`)";
4674 r = run_query(hdb, 0, query);
4675 ok(r == ERROR_BAD_QUERY_SYNTAX, "created _Streams table\n");
4677 query = "CREATE TABLE `_Streams` ( "
4678 "`foo` INT NOT NULL, `bar` INT LOCALIZABLE PRIMARY KEY `foo`)";
4679 r = run_query(hdb, 0, query);
4680 ok(r == ERROR_BAD_QUERY_SYNTAX, "created _Streams table\n");
4682 query = "CREATE TABLE `_Tables` ( "
4683 "`foo` INT NOT NULL, `bar` INT LOCALIZABLE PRIMARY KEY `foo`)";
4684 r = run_query(hdb, 0, query);
4685 ok(r == ERROR_BAD_QUERY_SYNTAX, "created _Tables table\n");
4687 query = "CREATE TABLE `_Columns` ( "
4688 "`foo` INT NOT NULL, `bar` INT LOCALIZABLE PRIMARY KEY `foo`)";
4689 r = run_query(hdb, 0, query);
4690 ok(r == ERROR_BAD_QUERY_SYNTAX, "created _Columns table\n");
4692 r = MsiCloseHandle(hdb);
4693 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
4696 static void test_tables_order(void)
4699 MSIHANDLE hdb = 0, hview = 0, hrec = 0;
4704 r = MsiOpenDatabase(msifile, MSIDBOPEN_CREATE, &hdb);
4705 ok(r == ERROR_SUCCESS, "MsiOpenDatabase failed\n");
4707 query = "CREATE TABLE `foo` ( "
4708 "`baz` INT NOT NULL PRIMARY KEY `baz`)";
4709 r = run_query(hdb, 0, query);
4710 ok(r == ERROR_SUCCESS, "failed to create table\n");
4712 query = "CREATE TABLE `bar` ( "
4713 "`foo` INT NOT NULL PRIMARY KEY `foo`)";
4714 r = run_query(hdb, 0, query);
4715 ok(r == ERROR_SUCCESS, "failed to create table\n");
4717 query = "CREATE TABLE `baz` ( "
4718 "`bar` INT NOT NULL, "
4719 "`baz` INT NOT NULL, "
4720 "`foo` INT NOT NULL PRIMARY KEY `bar`)";
4721 r = run_query(hdb, 0, query);
4722 ok(r == ERROR_SUCCESS, "failed to create table\n");
4724 /* The names of the tables in the _Tables table must
4725 be in the same order as these names are created in
4726 the strings table. */
4727 query = "SELECT * FROM `_Tables`";
4728 r = MsiDatabaseOpenView(hdb, query, &hview);
4729 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
4730 r = MsiViewExecute(hview, 0);
4731 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n");
4733 r = MsiViewFetch(hview, &hrec);
4734 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n");
4735 sz = sizeof(buffer);
4736 r = MsiRecordGetString(hrec, 1, buffer, &sz);
4737 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4738 ok(!lstrcmp(buffer, "foo"), "Expected foo, got %s\n", buffer);
4739 r = MsiCloseHandle(hrec);
4740 ok(r == ERROR_SUCCESS, "failed to close record\n");
4742 r = MsiViewFetch(hview, &hrec);
4743 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n");
4744 sz = sizeof(buffer);
4745 r = MsiRecordGetString(hrec, 1, buffer, &sz);
4746 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4747 ok(!lstrcmp(buffer, "baz"), "Expected baz, got %s\n", buffer);
4748 r = MsiCloseHandle(hrec);
4749 ok(r == ERROR_SUCCESS, "failed to close record\n");
4751 r = MsiViewFetch(hview, &hrec);
4752 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n");
4753 sz = sizeof(buffer);
4754 r = MsiRecordGetString(hrec, 1, buffer, &sz);
4755 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4756 ok(!lstrcmp(buffer, "bar"), "Expected bar, got %s\n", buffer);
4757 r = MsiCloseHandle(hrec);
4758 ok(r == ERROR_SUCCESS, "failed to close record\n");
4760 r = MsiViewClose(hview);
4761 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n");
4762 r = MsiCloseHandle(hview);
4763 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
4765 /* The names of the tables in the _Columns table must
4766 be in the same order as these names are created in
4767 the strings table. */
4768 query = "SELECT * FROM `_Columns`";
4769 r = MsiDatabaseOpenView(hdb, query, &hview);
4770 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
4771 r = MsiViewExecute(hview, 0);
4772 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n");
4774 r = MsiViewFetch(hview, &hrec);
4775 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n");
4776 sz = sizeof(buffer);
4777 r = MsiRecordGetString(hrec, 1, buffer, &sz);
4778 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4779 ok(!lstrcmp(buffer, "foo"), "Expected foo, got %s\n", buffer);
4780 sz = sizeof(buffer);
4781 r = MsiRecordGetString(hrec, 3, buffer, &sz);
4782 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4783 ok(!lstrcmp(buffer, "baz"), "Expected baz, got %s\n", buffer);
4784 r = MsiCloseHandle(hrec);
4785 ok(r == ERROR_SUCCESS, "failed to close record\n");
4787 r = MsiViewFetch(hview, &hrec);
4788 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n");
4789 sz = sizeof(buffer);
4790 r = MsiRecordGetString(hrec, 1, buffer, &sz);
4791 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4792 ok(!lstrcmp(buffer, "baz"), "Expected baz, got %s\n", buffer);
4793 sz = sizeof(buffer);
4794 r = MsiRecordGetString(hrec, 3, buffer, &sz);
4795 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4796 ok(!lstrcmp(buffer, "bar"), "Expected bar, got %s\n", buffer);
4797 r = MsiCloseHandle(hrec);
4798 ok(r == ERROR_SUCCESS, "failed to close record\n");
4800 r = MsiViewFetch(hview, &hrec);
4801 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n");
4802 sz = sizeof(buffer);
4803 r = MsiRecordGetString(hrec, 1, buffer, &sz);
4804 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4805 ok(!lstrcmp(buffer, "baz"), "Expected baz, got %s\n", buffer);
4806 sz = sizeof(buffer);
4807 r = MsiRecordGetString(hrec, 3, buffer, &sz);
4808 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4809 ok(!lstrcmp(buffer, "baz"), "Expected baz, got %s\n", buffer);
4810 r = MsiCloseHandle(hrec);
4811 ok(r == ERROR_SUCCESS, "failed to close record\n");
4813 r = MsiViewFetch(hview, &hrec);
4814 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n");
4815 sz = sizeof(buffer);
4816 r = MsiRecordGetString(hrec, 1, buffer, &sz);
4817 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4818 ok(!lstrcmp(buffer, "baz"), "Expected baz, got %s\n", buffer);
4819 sz = sizeof(buffer);
4820 r = MsiRecordGetString(hrec, 3, buffer, &sz);
4821 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4822 ok(!lstrcmp(buffer, "foo"), "Expected foo, got %s\n", buffer);
4823 r = MsiCloseHandle(hrec);
4824 ok(r == ERROR_SUCCESS, "failed to close record\n");
4826 r = MsiViewFetch(hview, &hrec);
4827 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n");
4828 sz = sizeof(buffer);
4829 r = MsiRecordGetString(hrec, 1, buffer, &sz);
4830 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4831 ok(!lstrcmp(buffer, "bar"), "Expected bar, got %s\n", buffer);
4832 sz = sizeof(buffer);
4833 r = MsiRecordGetString(hrec, 3, buffer, &sz);
4834 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4835 ok(!lstrcmp(buffer, "foo"), "Expected foo, got %s\n", buffer);
4836 r = MsiCloseHandle(hrec);
4837 ok(r == ERROR_SUCCESS, "failed to close record\n");
4839 r = MsiViewClose(hview);
4840 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n");
4841 r = MsiCloseHandle(hview);
4842 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
4844 r = MsiCloseHandle(hdb);
4845 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
4847 DeleteFile(msifile);
4850 static void test_rows_order(void)
4853 MSIHANDLE hdb = 0, hview = 0, hrec = 0;
4858 r = MsiOpenDatabase(msifile, MSIDBOPEN_CREATE, &hdb);
4859 ok(r == ERROR_SUCCESS, "MsiOpenDatabase failed\n");
4861 query = "CREATE TABLE `foo` ( "
4862 "`bar` LONGCHAR NOT NULL PRIMARY KEY `bar`)";
4863 r = run_query(hdb, 0, query);
4864 ok(r == ERROR_SUCCESS, "failed to create table\n");
4866 r = run_query(hdb, 0, "INSERT INTO `foo` "
4867 "( `bar` ) VALUES ( 'A' )");
4868 ok(r == ERROR_SUCCESS, "cannot add value to table\n");
4870 r = run_query(hdb, 0, "INSERT INTO `foo` "
4871 "( `bar` ) VALUES ( 'B' )");
4872 ok(r == ERROR_SUCCESS, "cannot add value to table\n");
4874 r = run_query(hdb, 0, "INSERT INTO `foo` "
4875 "( `bar` ) VALUES ( 'C' )");
4876 ok(r == ERROR_SUCCESS, "cannot add value to table\n");
4878 r = run_query(hdb, 0, "INSERT INTO `foo` "
4879 "( `bar` ) VALUES ( 'D' )");
4880 ok(r == ERROR_SUCCESS, "cannot add value to table\n");
4882 r = run_query(hdb, 0, "INSERT INTO `foo` "
4883 "( `bar` ) VALUES ( 'E' )");
4884 ok(r == ERROR_SUCCESS, "cannot add value to table\n");
4886 r = run_query(hdb, 0, "INSERT INTO `foo` "
4887 "( `bar` ) VALUES ( 'F' )");
4888 ok(r == ERROR_SUCCESS, "cannot add value to table\n");
4890 query = "CREATE TABLE `bar` ( "
4891 "`foo` LONGCHAR NOT NULL, "
4892 "`baz` LONGCHAR NOT NULL "
4893 "PRIMARY KEY `foo` )";
4894 r = run_query(hdb, 0, query);
4895 ok(r == ERROR_SUCCESS, "failed to create table\n");
4897 r = run_query(hdb, 0, "INSERT INTO `bar` "
4898 "( `foo`, `baz` ) VALUES ( 'C', 'E' )");
4899 ok(r == ERROR_SUCCESS, "cannot add value to table\n");
4901 r = run_query(hdb, 0, "INSERT INTO `bar` "
4902 "( `foo`, `baz` ) VALUES ( 'F', 'A' )");
4903 ok(r == ERROR_SUCCESS, "cannot add value to table\n");
4905 r = run_query(hdb, 0, "INSERT INTO `bar` "
4906 "( `foo`, `baz` ) VALUES ( 'A', 'B' )");
4907 ok(r == ERROR_SUCCESS, "cannot add value to table\n");
4909 r = run_query(hdb, 0, "INSERT INTO `bar` "
4910 "( `foo`, `baz` ) VALUES ( 'D', 'E' )");
4911 ok(r == ERROR_SUCCESS, "cannot add value to table\n");
4913 /* The rows of the table must be ordered by the column values of
4914 each row. For strings, the column value is the string id
4915 in the string table. */
4917 query = "SELECT * FROM `bar`";
4918 r = MsiDatabaseOpenView(hdb, query, &hview);
4919 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
4920 r = MsiViewExecute(hview, 0);
4921 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n");
4923 r = MsiViewFetch(hview, &hrec);
4924 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n");
4925 sz = sizeof(buffer);
4926 r = MsiRecordGetString(hrec, 1, buffer, &sz);
4927 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4928 ok(!lstrcmp(buffer, "A"), "Expected A, got %s\n", buffer);
4929 sz = sizeof(buffer);
4930 r = MsiRecordGetString(hrec, 2, buffer, &sz);
4931 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4932 ok(!lstrcmp(buffer, "B"), "Expected B, got %s\n", buffer);
4933 r = MsiCloseHandle(hrec);
4934 ok(r == ERROR_SUCCESS, "failed to close record\n");
4936 r = MsiViewFetch(hview, &hrec);
4937 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n");
4938 sz = sizeof(buffer);
4939 r = MsiRecordGetString(hrec, 1, buffer, &sz);
4940 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4941 ok(!lstrcmp(buffer, "C"), "Expected E, got %s\n", buffer);
4942 sz = sizeof(buffer);
4943 r = MsiRecordGetString(hrec, 2, buffer, &sz);
4944 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4945 ok(!lstrcmp(buffer, "E"), "Expected E, got %s\n", buffer);
4946 r = MsiCloseHandle(hrec);
4947 ok(r == ERROR_SUCCESS, "failed to close record\n");
4949 r = MsiViewFetch(hview, &hrec);
4950 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n");
4951 sz = sizeof(buffer);
4952 r = MsiRecordGetString(hrec, 1, buffer, &sz);
4953 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4954 ok(!lstrcmp(buffer, "D"), "Expected D, got %s\n", buffer);
4955 sz = sizeof(buffer);
4956 r = MsiRecordGetString(hrec, 2, buffer, &sz);
4957 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4958 ok(!lstrcmp(buffer, "E"), "Expected E, got %s\n", buffer);
4959 r = MsiCloseHandle(hrec);
4960 ok(r == ERROR_SUCCESS, "failed to close record\n");
4962 r = MsiViewFetch(hview, &hrec);
4963 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n");
4964 sz = sizeof(buffer);
4965 r = MsiRecordGetString(hrec, 1, buffer, &sz);
4966 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4967 ok(!lstrcmp(buffer, "F"), "Expected F, got %s\n", buffer);
4968 sz = sizeof(buffer);
4969 r = MsiRecordGetString(hrec, 2, buffer, &sz);
4970 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4971 ok(!lstrcmp(buffer, "A"), "Expected A, got %s\n", buffer);
4972 r = MsiCloseHandle(hrec);
4973 ok(r == ERROR_SUCCESS, "failed to close record\n");
4975 r = MsiViewClose(hview);
4976 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n");
4977 r = MsiCloseHandle(hview);
4978 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
4980 r = MsiCloseHandle(hdb);
4981 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
4983 DeleteFile(msifile);
4986 static void test_collation(void)
4988 static const WCHAR query1[] =
4989 {'I','N','S','E','R','T',' ','I','N','T','O',' ','`','b','a','r','`',' ',
4990 '(','`','f','o','o','`',',','`','b','a','z','`',')',' ','V','A','L','U','E','S',' ',
4991 '(','\'','a',0x30a,'\'',',','\'','C','\'',')',0};
4992 static const WCHAR query2[] =
4993 {'I','N','S','E','R','T',' ','I','N','T','O',' ','`','b','a','r','`',' ',
4994 '(','`','f','o','o','`',',','`','b','a','z','`',')',' ','V','A','L','U','E','S',' ',
4995 '(','\'',0xe5,'\'',',','\'','D','\'',')',0};
4996 static const WCHAR query3[] =
4997 {'C','R','E','A','T','E',' ','T','A','B','L','E',' ','`','b','a','z','`',' ',
4998 '(',' ','`','a',0x30a,'`',' ','L','O','N','G','C','H','A','R',' ','N','O','T',' ','N','U','L','L',',',
4999 ' ','`',0xe5,'`',' ','L','O','N','G','C','H','A','R',' ','N','O','T',' ','N','U','L','L',' ',
5000 'P','R','I','M','A','R','Y',' ','K','E','Y',' ','`','a',0x30a,'`',')',0};
5001 static const WCHAR query4[] =
5002 {'C','R','E','A','T','E',' ','T','A','B','L','E',' ','`','a',0x30a,'`',' ',
5003 '(',' ','`','f','o','o','`',' ','L','O','N','G','C','H','A','R',' ','N','O','T',' ',
5004 'N','U','L','L',' ','P','R','I','M','A','R','Y',' ','K','E','Y',' ','`','f','o','o','`',')',0};
5005 static const WCHAR query5[] =
5006 {'C','R','E','A','T','E',' ','T','A','B','L','E',' ','`',0xe5,'`',' ',
5007 '(',' ','`','f','o','o','`',' ','L','O','N','G','C','H','A','R',' ','N','O','T',' ',
5008 'N','U','L','L',' ','P','R','I','M','A','R','Y',' ','K','E','Y',' ','`','f','o','o','`',')',0};
5009 static const WCHAR query6[] =
5010 {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ','`','b','a','r','`',' ','W','H','E','R','E',
5011 ' ','`','f','o','o','`',' ','=','\'',0xe5,'\'',0};
5012 static const WCHAR letter_C[] = {'C',0};
5013 static const WCHAR letter_D[] = {'D',0};
5014 static const WCHAR letter_a_ring[] = {'a',0x30a,0};
5015 static const WCHAR letter_a_with_ring[] = {0xe5,0};
5017 MSIHANDLE hdb = 0, hview = 0, hrec = 0;
5023 r = MsiOpenDatabase(msifile, MSIDBOPEN_CREATE, &hdb);
5024 ok(r == ERROR_SUCCESS, "MsiOpenDatabase failed\n");
5026 query = "CREATE TABLE `bar` ( "
5027 "`foo` LONGCHAR NOT NULL, "
5028 "`baz` LONGCHAR NOT NULL "
5029 "PRIMARY KEY `foo` )";
5030 r = run_query(hdb, 0, query);
5031 ok(r == ERROR_SUCCESS, "failed to create table\n");
5033 r = run_query(hdb, 0, query);
5034 ok(r == ERROR_BAD_QUERY_SYNTAX, "wrong error %u\n", r);
5036 r = run_query(hdb, 0, "INSERT INTO `bar` "
5037 "( `foo`, `baz` ) VALUES ( '\2', 'A' )");
5038 ok(r == ERROR_SUCCESS, "cannot add value to table %u\n", r);
5040 r = run_query(hdb, 0, "INSERT INTO `bar` "
5041 "( `foo`, `baz` ) VALUES ( '\1', 'B' )");
5042 ok(r == ERROR_SUCCESS, "cannot add value to table %u\n", r);
5044 r = run_queryW(hdb, 0, query1);
5045 ok(r == ERROR_SUCCESS, "cannot add value to table %u\n", r);
5047 r = run_queryW(hdb, 0, query2);
5048 ok(r == ERROR_SUCCESS, "cannot add value to table %u\n", r);
5050 r = run_queryW(hdb, 0, query3);
5051 ok(r == ERROR_SUCCESS, "cannot create table %u\n", r);
5053 r = run_queryW(hdb, 0, query4);
5054 ok(r == ERROR_SUCCESS, "cannot create table %u\n", r);
5056 r = run_queryW(hdb, 0, query5);
5057 ok(r == ERROR_SUCCESS, "cannot create table %u\n", r);
5059 query = "SELECT * FROM `bar`";
5060 r = MsiDatabaseOpenView(hdb, query, &hview);
5061 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
5062 r = MsiViewExecute(hview, 0);
5063 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n");
5065 r = MsiViewFetch(hview, &hrec);
5066 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n");
5067 sz = sizeof(buffer);
5068 r = MsiRecordGetString(hrec, 1, buffer, &sz);
5069 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5070 ok(!lstrcmp(buffer, "\2"), "Expected \\2, got '%s'\n", buffer);
5071 sz = sizeof(buffer);
5072 r = MsiRecordGetString(hrec, 2, buffer, &sz);
5073 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5074 ok(!lstrcmp(buffer, "A"), "Expected A, got '%s'\n", buffer);
5075 MsiCloseHandle(hrec);
5077 r = MsiViewFetch(hview, &hrec);
5078 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n");
5079 sz = sizeof(buffer);
5080 r = MsiRecordGetString(hrec, 1, buffer, &sz);
5081 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5082 ok(!lstrcmp(buffer, "\1"), "Expected \\1, got '%s'\n", buffer);
5083 sz = sizeof(buffer);
5084 r = MsiRecordGetString(hrec, 2, buffer, &sz);
5085 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5086 ok(!lstrcmp(buffer, "B"), "Expected B, got '%s'\n", buffer);
5087 MsiCloseHandle(hrec);
5089 r = MsiViewFetch(hview, &hrec);
5090 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n");
5091 sz = sizeof(bufferW) / sizeof(bufferW[0]);
5092 r = MsiRecordGetStringW(hrec, 1, bufferW, &sz);
5093 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5094 ok(!memcmp(bufferW, letter_a_ring, sizeof(letter_a_ring)),
5095 "Expected %s, got %s\n", wine_dbgstr_w(letter_a_ring), wine_dbgstr_w(bufferW));
5096 sz = sizeof(bufferW) / sizeof(bufferW[0]);
5097 r = MsiRecordGetStringW(hrec, 2, bufferW, &sz);
5098 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5099 ok(!lstrcmpW(bufferW, letter_C), "Expected C, got %s\n", wine_dbgstr_w(bufferW));
5100 MsiCloseHandle(hrec);
5102 r = MsiViewFetch(hview, &hrec);
5103 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n");
5104 sz = sizeof(bufferW) / sizeof(bufferW[0]);
5105 r = MsiRecordGetStringW(hrec, 1, bufferW, &sz);
5106 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5107 ok(!memcmp(bufferW, letter_a_with_ring, sizeof(letter_a_with_ring)),
5108 "Expected %s, got %s\n", wine_dbgstr_w(letter_a_with_ring), wine_dbgstr_w(bufferW));
5109 sz = sizeof(bufferW) / sizeof(bufferW[0]);
5110 r = MsiRecordGetStringW(hrec, 2, bufferW, &sz);
5111 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5112 ok(!lstrcmpW(bufferW, letter_D), "Expected D, got %s\n", wine_dbgstr_w(bufferW));
5113 MsiCloseHandle(hrec);
5115 r = MsiViewClose(hview);
5116 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n");
5117 r = MsiCloseHandle(hview);
5118 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
5120 r = MsiDatabaseOpenViewW(hdb, query6, &hview);
5121 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
5122 r = MsiViewExecute(hview, 0);
5123 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n");
5125 r = MsiViewFetch(hview, &hrec);
5126 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n");
5127 sz = sizeof(bufferW) / sizeof(bufferW[0]);
5128 r = MsiRecordGetStringW(hrec, 1, bufferW, &sz);
5129 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5130 ok(!memcmp(bufferW, letter_a_with_ring, sizeof(letter_a_with_ring)),
5131 "Expected %s, got %s\n", wine_dbgstr_w(letter_a_with_ring), wine_dbgstr_w(bufferW));
5132 sz = sizeof(bufferW) / sizeof(bufferW[0]);
5133 r = MsiRecordGetStringW(hrec, 2, bufferW, &sz);
5134 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5135 ok(!lstrcmpW(bufferW, letter_D), "Expected D, got %s\n", wine_dbgstr_w(bufferW));
5136 MsiCloseHandle(hrec);
5138 r = MsiViewFetch(hview, &hrec);
5139 ok(r == ERROR_NO_MORE_ITEMS, "MsiViewFetch failed\n");
5141 r = MsiViewClose(hview);
5142 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n");
5143 r = MsiCloseHandle(hview);
5144 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
5146 r = MsiCloseHandle(hdb);
5147 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
5149 DeleteFile(msifile);
5152 static void test_select_markers(void)
5154 MSIHANDLE hdb = 0, rec, view, res;
5161 ok( hdb, "failed to create db\n");
5163 r = run_query(hdb, 0,
5164 "CREATE TABLE `Table` (`One` CHAR(72), `Two` CHAR(72), `Three` SHORT PRIMARY KEY `One`, `Two`, `Three`)");
5165 ok(r == S_OK, "cannot create table: %d\n", r);
5167 r = run_query(hdb, 0, "INSERT INTO `Table` "
5168 "( `One`, `Two`, `Three` ) VALUES ( 'apple', 'one', 1 )");
5169 ok(r == S_OK, "cannot add file to the Media table: %d\n", r);
5171 r = run_query(hdb, 0, "INSERT INTO `Table` "
5172 "( `One`, `Two`, `Three` ) VALUES ( 'apple', 'two', 1 )");
5173 ok(r == S_OK, "cannot add file to the Media table: %d\n", r);
5175 r = run_query(hdb, 0, "INSERT INTO `Table` "
5176 "( `One`, `Two`, `Three` ) VALUES ( 'apple', 'two', 2 )");
5177 ok(r == S_OK, "cannot add file to the Media table: %d\n", r);
5179 r = run_query(hdb, 0, "INSERT INTO `Table` "
5180 "( `One`, `Two`, `Three` ) VALUES ( 'banana', 'three', 3 )");
5181 ok(r == S_OK, "cannot add file to the Media table: %d\n", r);
5183 rec = MsiCreateRecord(2);
5184 MsiRecordSetString(rec, 1, "apple");
5185 MsiRecordSetString(rec, 2, "two");
5187 query = "SELECT * FROM `Table` WHERE `One`=? AND `Two`=? ORDER BY `Three`";
5188 r = MsiDatabaseOpenView(hdb, query, &view);
5189 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5191 r = MsiViewExecute(view, rec);
5192 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5194 r = MsiViewFetch(view, &res);
5195 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5198 r = MsiRecordGetString(res, 1, buf, &size);
5199 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5200 ok(!lstrcmp(buf, "apple"), "Expected apple, got %s\n", buf);
5203 r = MsiRecordGetString(res, 2, buf, &size);
5204 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5205 ok(!lstrcmp(buf, "two"), "Expected two, got %s\n", buf);
5207 r = MsiRecordGetInteger(res, 3);
5208 ok(r == 1, "Expected 1, got %d\n", r);
5210 MsiCloseHandle(res);
5212 r = MsiViewFetch(view, &res);
5213 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5216 r = MsiRecordGetString(res, 1, buf, &size);
5217 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5218 ok(!lstrcmp(buf, "apple"), "Expected apple, got %s\n", buf);
5221 r = MsiRecordGetString(res, 2, buf, &size);
5222 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5223 ok(!lstrcmp(buf, "two"), "Expected two, got %s\n", buf);
5225 r = MsiRecordGetInteger(res, 3);
5226 ok(r == 2, "Expected 2, got %d\n", r);
5228 MsiCloseHandle(res);
5230 r = MsiViewFetch(view, &res);
5231 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
5233 MsiCloseHandle(rec);
5235 MsiCloseHandle(view);
5237 rec = MsiCreateRecord(2);
5238 MsiRecordSetString(rec, 1, "one");
5239 MsiRecordSetInteger(rec, 2, 1);
5241 query = "SELECT * FROM `Table` WHERE `Two`<>? AND `Three`>? ORDER BY `Three`";
5242 r = MsiDatabaseOpenView(hdb, query, &view);
5243 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5244 r = MsiViewExecute(view, rec);
5245 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5247 r = MsiViewFetch(view, &res);
5248 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5251 r = MsiRecordGetString(res, 1, buf, &size);
5252 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5253 ok(!lstrcmp(buf, "apple"), "Expected apple, got %s\n", buf);
5256 r = MsiRecordGetString(res, 2, buf, &size);
5257 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5258 ok(!lstrcmp(buf, "two"), "Expected two, got %s\n", buf);
5260 r = MsiRecordGetInteger(res, 3);
5261 ok(r == 2, "Expected 2, got %d\n", r);
5263 MsiCloseHandle(res);
5265 r = MsiViewFetch(view, &res);
5266 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5269 r = MsiRecordGetString(res, 1, buf, &size);
5270 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5271 ok(!lstrcmp(buf, "banana"), "Expected banana, got %s\n", buf);
5274 r = MsiRecordGetString(res, 2, buf, &size);
5275 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5276 ok(!lstrcmp(buf, "three"), "Expected three, got %s\n", buf);
5278 r = MsiRecordGetInteger(res, 3);
5279 ok(r == 3, "Expected 3, got %d\n", r);
5281 MsiCloseHandle(res);
5283 r = MsiViewFetch(view, &res);
5284 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
5286 MsiCloseHandle(rec);
5288 MsiCloseHandle(view);
5289 MsiCloseHandle(hdb);
5290 DeleteFile(msifile);
5293 static void test_viewmodify_update(void)
5295 MSIHANDLE hdb = 0, hview = 0, hrec = 0;
5296 UINT i, test_max, offset, count;
5300 DeleteFile(msifile);
5302 r = MsiOpenDatabase(msifile, MSIDBOPEN_CREATE, &hdb);
5303 ok(r == ERROR_SUCCESS, "MsiOpenDatabase failed\n");
5305 query = "CREATE TABLE `table` (`A` INT, `B` INT PRIMARY KEY `A`)";
5306 r = run_query( hdb, 0, query );
5307 ok(r == ERROR_SUCCESS, "query failed\n");
5309 query = "INSERT INTO `table` (`A`, `B`) VALUES (1, 2)";
5310 r = run_query( hdb, 0, query );
5311 ok(r == ERROR_SUCCESS, "query failed\n");
5313 query = "INSERT INTO `table` (`A`, `B`) VALUES (3, 4)";
5314 r = run_query( hdb, 0, query );
5315 ok(r == ERROR_SUCCESS, "query failed\n");
5317 query = "INSERT INTO `table` (`A`, `B`) VALUES (5, 6)";
5318 r = run_query( hdb, 0, query );
5319 ok(r == ERROR_SUCCESS, "query failed\n");
5321 query = "SELECT `B` FROM `table`";
5322 r = MsiDatabaseOpenView(hdb, query, &hview);
5323 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
5324 r = MsiViewExecute(hview, 0);
5325 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n");
5326 r = MsiViewFetch(hview, &hrec);
5327 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n");
5329 r = MsiRecordSetInteger(hrec, 1, 0);
5330 ok(r == ERROR_SUCCESS, "failed to set integer\n");
5332 r = MsiViewModify(hview, MSIMODIFY_UPDATE, hrec);
5333 ok(r == ERROR_SUCCESS, "MsiViewModify failed: %d\n", r);
5335 r = MsiCloseHandle(hrec);
5336 ok(r == ERROR_SUCCESS, "failed to close record\n");
5338 r = MsiViewClose(hview);
5339 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n");
5340 r = MsiCloseHandle(hview);
5341 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
5343 query = "SELECT * FROM `table`";
5344 r = MsiDatabaseOpenView(hdb, query, &hview);
5345 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
5346 r = MsiViewExecute(hview, 0);
5347 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n");
5348 r = MsiViewFetch(hview, &hrec);
5349 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n");
5351 r = MsiRecordGetInteger(hrec, 1);
5352 ok(r == 1, "Expected 1, got %d\n", r);
5353 r = MsiRecordGetInteger(hrec, 2);
5354 ok(r == 0, "Expected 0, got %d\n", r);
5356 r = MsiCloseHandle(hrec);
5357 ok(r == ERROR_SUCCESS, "failed to close record\n");
5359 r = MsiViewFetch(hview, &hrec);
5360 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n");
5362 r = MsiRecordGetInteger(hrec, 1);
5363 ok(r == 3, "Expected 3, got %d\n", r);
5364 r = MsiRecordGetInteger(hrec, 2);
5365 ok(r == 4, "Expected 4, got %d\n", r);
5367 r = MsiCloseHandle(hrec);
5368 ok(r == ERROR_SUCCESS, "failed to close record\n");
5370 r = MsiViewFetch(hview, &hrec);
5371 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n");
5373 r = MsiRecordGetInteger(hrec, 1);
5374 ok(r == 5, "Expected 5, got %d\n", r);
5375 r = MsiRecordGetInteger(hrec, 2);
5376 ok(r == 6, "Expected 6, got %d\n", r);
5378 r = MsiCloseHandle(hrec);
5379 ok(r == ERROR_SUCCESS, "failed to close record\n");
5381 r = MsiViewFetch(hview, &hrec);
5382 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
5384 r = MsiViewClose(hview);
5385 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n");
5386 r = MsiCloseHandle(hview);
5387 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
5389 /* loop through all elements */
5390 query = "SELECT `B` FROM `table`";
5391 r = MsiDatabaseOpenView(hdb, query, &hview);
5392 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
5393 r = MsiViewExecute(hview, 0);
5394 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n");
5398 r = MsiViewFetch(hview, &hrec);
5399 if (r != ERROR_SUCCESS)
5402 r = MsiRecordSetInteger(hrec, 1, 0);
5403 ok(r == ERROR_SUCCESS, "failed to set integer\n");
5405 r = MsiViewModify(hview, MSIMODIFY_UPDATE, hrec);
5406 ok(r == ERROR_SUCCESS, "MsiViewModify failed: %d\n", r);
5408 r = MsiCloseHandle(hrec);
5409 ok(r == ERROR_SUCCESS, "failed to close record\n");
5412 r = MsiViewClose(hview);
5413 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n");
5414 r = MsiCloseHandle(hview);
5415 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
5417 query = "SELECT * FROM `table`";
5418 r = MsiDatabaseOpenView(hdb, query, &hview);
5419 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
5420 r = MsiViewExecute(hview, 0);
5421 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n");
5422 r = MsiViewFetch(hview, &hrec);
5423 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n");
5425 r = MsiRecordGetInteger(hrec, 1);
5426 ok(r == 1, "Expected 1, got %d\n", r);
5427 r = MsiRecordGetInteger(hrec, 2);
5428 ok(r == 0, "Expected 0, got %d\n", r);
5430 r = MsiCloseHandle(hrec);
5431 ok(r == ERROR_SUCCESS, "failed to close record\n");
5433 r = MsiViewFetch(hview, &hrec);
5434 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n");
5436 r = MsiRecordGetInteger(hrec, 1);
5437 ok(r == 3, "Expected 3, got %d\n", r);
5438 r = MsiRecordGetInteger(hrec, 2);
5439 ok(r == 0, "Expected 0, got %d\n", r);
5441 r = MsiCloseHandle(hrec);
5442 ok(r == ERROR_SUCCESS, "failed to close record\n");
5444 r = MsiViewFetch(hview, &hrec);
5445 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n");
5447 r = MsiRecordGetInteger(hrec, 1);
5448 ok(r == 5, "Expected 5, got %d\n", r);
5449 r = MsiRecordGetInteger(hrec, 2);
5450 ok(r == 0, "Expected 0, got %d\n", r);
5452 r = MsiCloseHandle(hrec);
5453 ok(r == ERROR_SUCCESS, "failed to close record\n");
5455 r = MsiViewFetch(hview, &hrec);
5456 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
5458 r = MsiViewClose(hview);
5459 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n");
5460 r = MsiCloseHandle(hview);
5461 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
5463 query = "CREATE TABLE `table2` (`A` INT, `B` INT PRIMARY KEY `A`)";
5464 r = run_query( hdb, 0, query );
5465 ok(r == ERROR_SUCCESS, "query failed\n");
5467 query = "INSERT INTO `table2` (`A`, `B`) VALUES (?, ?)";
5468 r = MsiDatabaseOpenView( hdb, query, &hview );
5469 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
5473 for(i = 0; i < test_max; i++)
5476 hrec = MsiCreateRecord( 2 );
5477 MsiRecordSetInteger( hrec, 1, test_max - i );
5478 MsiRecordSetInteger( hrec, 2, i );
5480 r = MsiViewExecute( hview, hrec );
5481 ok(r == ERROR_SUCCESS, "Got %d\n", r);
5483 r = MsiCloseHandle( hrec );
5484 ok(r == ERROR_SUCCESS, "Got %d\n", r);
5487 r = MsiViewClose( hview );
5488 ok(r == ERROR_SUCCESS, "Got %d\n", r);
5489 r = MsiCloseHandle( hview );
5490 ok(r == ERROR_SUCCESS, "Got %d\n", r);
5493 query = "SELECT * FROM `table2` ORDER BY `B`";
5494 r = MsiDatabaseOpenView( hdb, query, &hview);
5495 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
5496 r = MsiViewExecute( hview, 0 );
5497 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n");
5500 while (MsiViewFetch( hview, &hrec ) == ERROR_SUCCESS)
5502 UINT b = MsiRecordGetInteger( hrec, 2 );
5504 r = MsiRecordSetInteger( hrec, 2, b + offset);
5505 ok(r == ERROR_SUCCESS, "Got %d\n", r);
5507 r = MsiViewModify( hview, MSIMODIFY_UPDATE, hrec );
5508 ok(r == ERROR_SUCCESS, "Got %d\n", r);
5510 r = MsiCloseHandle(hrec);
5511 ok(r == ERROR_SUCCESS, "failed to close record\n");
5514 ok(count == test_max, "Got count %d\n", count);
5516 r = MsiViewClose(hview);
5517 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n");
5518 r = MsiCloseHandle(hview);
5519 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
5522 query = "SELECT * FROM `table2` ORDER BY `B`";
5523 r = MsiDatabaseOpenView( hdb, query, &hview);
5524 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
5525 r = MsiViewExecute( hview, 0 );
5526 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n");
5529 while (MsiViewFetch( hview, &hrec ) == ERROR_SUCCESS)
5531 UINT a = MsiRecordGetInteger( hrec, 1 );
5532 UINT b = MsiRecordGetInteger( hrec, 2 );
5533 ok( ( test_max - a + offset) == b, "Got (%d, %d), expected (%d, %d)\n",
5534 a, b, test_max - a + offset, b);
5536 r = MsiCloseHandle(hrec);
5537 ok(r == ERROR_SUCCESS, "failed to close record\n");
5540 ok(count == test_max, "Got count %d\n", count);
5542 r = MsiViewClose(hview);
5543 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n");
5544 r = MsiCloseHandle(hview);
5545 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
5547 r = MsiCloseHandle( hdb );
5548 ok(r == ERROR_SUCCESS, "MsiOpenDatabase close failed\n");
5551 static void test_viewmodify_assign(void)
5553 MSIHANDLE hdb = 0, hview = 0, hrec = 0;
5557 /* setup database */
5558 DeleteFile(msifile);
5560 r = MsiOpenDatabase(msifile, MSIDBOPEN_CREATE, &hdb);
5561 ok(r == ERROR_SUCCESS, "MsiOpenDatabase failed\n");
5563 query = "CREATE TABLE `table` (`A` INT, `B` INT PRIMARY KEY `A`)";
5564 r = run_query( hdb, 0, query );
5565 ok(r == ERROR_SUCCESS, "query failed\n");
5567 /* assign to view, new primary key */
5568 query = "SELECT * FROM `table`";
5569 r = MsiDatabaseOpenView(hdb, query, &hview);
5570 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
5571 r = MsiViewExecute(hview, 0);
5572 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n");
5574 hrec = MsiCreateRecord(2);
5575 ok(hrec != 0, "MsiCreateRecord failed\n");
5577 r = MsiRecordSetInteger(hrec, 1, 1);
5578 ok(r == ERROR_SUCCESS, "failed to set integer\n");
5579 r = MsiRecordSetInteger(hrec, 2, 2);
5580 ok(r == ERROR_SUCCESS, "failed to set integer\n");
5582 r = MsiViewModify(hview, MSIMODIFY_ASSIGN, hrec);
5583 ok(r == ERROR_SUCCESS, "MsiViewModify failed: %d\n", r);
5585 r = MsiCloseHandle(hrec);
5586 ok(r == ERROR_SUCCESS, "failed to close record\n");
5588 r = MsiViewClose(hview);
5589 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n");
5590 r = MsiCloseHandle(hview);
5591 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
5593 query = "SELECT * FROM `table`";
5594 r = MsiDatabaseOpenView(hdb, query, &hview);
5595 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
5596 r = MsiViewExecute(hview, 0);
5597 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n");
5598 r = MsiViewFetch(hview, &hrec);
5599 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n");
5601 r = MsiRecordGetInteger(hrec, 1);
5602 ok(r == 1, "Expected 1, got %d\n", r);
5603 r = MsiRecordGetInteger(hrec, 2);
5604 ok(r == 2, "Expected 2, got %d\n", r);
5606 r = MsiCloseHandle(hrec);
5607 ok(r == ERROR_SUCCESS, "failed to close record\n");
5609 r = MsiViewFetch(hview, &hrec);
5610 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
5612 r = MsiViewClose(hview);
5613 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n");
5614 r = MsiCloseHandle(hview);
5615 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
5617 /* assign to view, primary key matches */
5618 query = "SELECT * FROM `table`";
5619 r = MsiDatabaseOpenView(hdb, query, &hview);
5620 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
5621 r = MsiViewExecute(hview, 0);
5622 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n");
5624 hrec = MsiCreateRecord(2);
5625 ok(hrec != 0, "MsiCreateRecord failed\n");
5627 r = MsiRecordSetInteger(hrec, 1, 1);
5628 ok(r == ERROR_SUCCESS, "failed to set integer\n");
5629 r = MsiRecordSetInteger(hrec, 2, 4);
5630 ok(r == ERROR_SUCCESS, "failed to set integer\n");
5632 r = MsiViewModify(hview, MSIMODIFY_ASSIGN, hrec);
5633 ok(r == ERROR_SUCCESS, "MsiViewModify failed: %d\n", r);
5635 r = MsiCloseHandle(hrec);
5636 ok(r == ERROR_SUCCESS, "failed to close record\n");
5638 r = MsiViewClose(hview);
5639 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n");
5640 r = MsiCloseHandle(hview);
5641 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
5643 query = "SELECT * FROM `table`";
5644 r = MsiDatabaseOpenView(hdb, query, &hview);
5645 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
5646 r = MsiViewExecute(hview, 0);
5647 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n");
5648 r = MsiViewFetch(hview, &hrec);
5649 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n");
5651 r = MsiRecordGetInteger(hrec, 1);
5652 ok(r == 1, "Expected 1, got %d\n", r);
5653 r = MsiRecordGetInteger(hrec, 2);
5654 ok(r == 4, "Expected 4, got %d\n", r);
5656 r = MsiCloseHandle(hrec);
5657 ok(r == ERROR_SUCCESS, "failed to close record\n");
5659 r = MsiViewFetch(hview, &hrec);
5660 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
5662 r = MsiViewClose(hview);
5663 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n");
5664 r = MsiCloseHandle(hview);
5665 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
5667 /* close database */
5668 r = MsiCloseHandle( hdb );
5669 ok(r == ERROR_SUCCESS, "MsiOpenDatabase close failed\n");
5672 static const WCHAR data10[] = { /* MOO */
5675 static const WCHAR data11[] = { /* AAR */
5679 static const char data12[] = /* _StringData */
5680 "MOOABAARCDonetwofourfive";
5681 static const WCHAR data13[] = { /* _StringPool */
5683 0, 0, /* string 0 '' */
5684 0, 0, /* string 1 '' */
5685 0, 0, /* string 2 '' */
5686 0, 0, /* string 3 '' */
5687 0, 0, /* string 4 '' */
5688 3, 3, /* string 5 'MOO' */
5689 1, 1, /* string 6 'A' */
5690 1, 1, /* string 7 'B' */
5691 3, 3, /* string 8 'AAR' */
5692 1, 1, /* string 9 'C' */
5693 1, 1, /* string a 'D' */
5694 3, 1, /* string b 'one' */
5695 3, 1, /* string c 'two' */
5696 0, 0, /* string d '' */
5697 4, 1, /* string e 'four' */
5698 4, 1, /* string f 'five' */
5701 static void test_stringtable(void)
5703 MSIHANDLE hdb = 0, hview = 0, hrec = 0;
5704 IStorage *stg = NULL;
5709 char buffer[MAX_PATH];
5710 WCHAR data[MAX_PATH];
5714 static const DWORD mode = STGM_DIRECT | STGM_READ | STGM_SHARE_DENY_WRITE;
5715 static const WCHAR stringdata[] = {0x4840, 0x3f3f, 0x4577, 0x446c, 0x3b6a, 0x45e4, 0x4824, 0}; /* _StringData */
5716 static const WCHAR stringpool[] = {0x4840, 0x3f3f, 0x4577, 0x446c, 0x3e6a, 0x44b2, 0x482f, 0}; /* _StringPool */
5717 static const WCHAR moo[] = {0x4840, 0x3e16, 0x4818, 0}; /* MOO */
5718 static const WCHAR aar[] = {0x4840, 0x3a8a, 0x481b, 0}; /* AAR */
5720 DeleteFile(msifile);
5722 r = MsiOpenDatabase(msifile, MSIDBOPEN_CREATE, &hdb);
5723 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5725 query = "CREATE TABLE `MOO` (`A` INT, `B` CHAR(72) PRIMARY KEY `A`)";
5726 r = run_query(hdb, 0, query);
5727 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5729 query = "CREATE TABLE `AAR` (`C` INT, `D` CHAR(72) PRIMARY KEY `C`)";
5730 r = run_query(hdb, 0, query);
5731 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5733 /* insert persistent row */
5734 query = "INSERT INTO `MOO` (`A`, `B`) VALUES (1, 'one')";
5735 r = run_query(hdb, 0, query);
5736 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5738 /* insert persistent row */
5739 query = "INSERT INTO `AAR` (`C`, `D`) VALUES (2, 'two')";
5740 r = run_query(hdb, 0, query);
5741 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5744 query = "SELECT * FROM `MOO`";
5745 r = MsiDatabaseOpenView(hdb, query, &hview);
5746 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5747 r = MsiViewExecute(hview, 0);
5748 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5750 hrec = MsiCreateRecord(2);
5752 r = MsiRecordSetInteger(hrec, 1, 3);
5753 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5754 r = MsiRecordSetString(hrec, 2, "three");
5755 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5757 /* insert a nonpersistent row */
5758 r = MsiViewModify(hview, MSIMODIFY_INSERT_TEMPORARY, hrec);
5759 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5761 r = MsiCloseHandle(hrec);
5762 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5763 r = MsiViewClose(hview);
5764 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5765 r = MsiCloseHandle(hview);
5766 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5768 /* insert persistent row */
5769 query = "INSERT INTO `MOO` (`A`, `B`) VALUES (4, 'four')";
5770 r = run_query(hdb, 0, query);
5771 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5773 /* insert persistent row */
5774 query = "INSERT INTO `AAR` (`C`, `D`) VALUES (5, 'five')";
5775 r = run_query(hdb, 0, query);
5776 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5778 r = MsiDatabaseCommit(hdb);
5779 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5781 r = MsiCloseHandle(hdb);
5782 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5784 r = MsiOpenDatabase(msifile, MSIDBOPEN_READONLY, &hdb);
5785 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5787 query = "SELECT * FROM `MOO`";
5788 r = MsiDatabaseOpenView(hdb, query, &hview);
5789 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5791 r = MsiViewExecute(hview, 0);
5792 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5794 r = MsiViewFetch(hview, &hrec);
5795 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5797 r = MsiRecordGetFieldCount(hrec);
5798 ok(r == 2, "Expected 2, got %d\n", r);
5800 r = MsiRecordGetInteger(hrec, 1);
5801 ok(r == 1, "Expected 1, got %d\n", r);
5803 sz = sizeof(buffer);
5804 r = MsiRecordGetString(hrec, 2, buffer, &sz);
5805 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5806 ok(!lstrcmp(buffer, "one"), "Expected one, got '%s'\n", buffer);
5808 r = MsiCloseHandle(hrec);
5809 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5811 r = MsiViewFetch(hview, &hrec);
5812 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
5814 r = MsiViewClose(hview);
5815 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5816 r = MsiCloseHandle(hview);
5817 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5818 r = MsiCloseHandle(hrec);
5819 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5821 query = "SELECT * FROM `AAR`";
5822 r = MsiDatabaseOpenView(hdb, query, &hview);
5823 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5825 r = MsiViewExecute(hview, 0);
5826 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5828 r = MsiViewFetch(hview, &hrec);
5829 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5831 r = MsiRecordGetFieldCount(hrec);
5832 ok(r == 2, "Expected 2, got %d\n", r);
5834 r = MsiRecordGetInteger(hrec, 1);
5835 ok(r == 2, "Expected 2, got %d\n", r);
5837 sz = sizeof(buffer);
5838 r = MsiRecordGetString(hrec, 2, buffer, &sz);
5839 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5840 ok(!lstrcmp(buffer, "two"), "Expected two, got '%s'\n", buffer);
5842 r = MsiCloseHandle(hrec);
5843 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5845 r = MsiViewFetch(hview, &hrec);
5846 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5848 r = MsiRecordGetFieldCount(hrec);
5849 ok(r == 2, "Expected 2, got %d\n", r);
5851 r = MsiRecordGetInteger(hrec, 1);
5852 ok(r == 5, "Expected 5, got %d\n", r);
5854 sz = sizeof(buffer);
5855 r = MsiRecordGetString(hrec, 2, buffer, &sz);
5856 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5857 ok(!lstrcmp(buffer, "five"), "Expected five, got '%s'\n", buffer);
5859 r = MsiCloseHandle(hrec);
5860 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5862 r = MsiViewFetch(hview, &hrec);
5863 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
5865 r = MsiViewClose(hview);
5866 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5867 r = MsiCloseHandle(hview);
5868 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5869 r = MsiCloseHandle(hrec);
5870 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5871 r = MsiCloseHandle(hdb);
5872 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5874 MultiByteToWideChar(CP_ACP, 0, msifile, -1, name, 0x20);
5875 hr = StgOpenStorage(name, NULL, mode, NULL, 0, &stg);
5876 ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
5877 ok(stg != NULL, "Expected non-NULL storage\n");
5879 hr = IStorage_OpenStream(stg, moo, NULL, STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &stm);
5880 ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
5881 ok(stm != NULL, "Expected non-NULL stream\n");
5883 hr = IStream_Read(stm, data, MAX_PATH, &read);
5884 ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
5885 ok(read == 4, "Expected 4, got %d\n", read);
5886 todo_wine ok(!memcmp(data, data10, read), "Unexpected data\n");
5888 hr = IStream_Release(stm);
5889 ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
5891 hr = IStorage_OpenStream(stg, aar, NULL, STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &stm);
5892 ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
5893 ok(stm != NULL, "Expected non-NULL stream\n");
5895 hr = IStream_Read(stm, data, MAX_PATH, &read);
5896 ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
5897 ok(read == 8, "Expected 8, got %d\n", read);
5900 ok(!memcmp(data, data11, read), "Unexpected data\n");
5903 hr = IStream_Release(stm);
5904 ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
5906 hr = IStorage_OpenStream(stg, stringdata, NULL, STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &stm);
5907 ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
5908 ok(stm != NULL, "Expected non-NULL stream\n");
5910 hr = IStream_Read(stm, buffer, MAX_PATH, &read);
5911 ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
5912 ok(read == 24, "Expected 24, got %d\n", read);
5913 ok(!memcmp(buffer, data12, read), "Unexpected data\n");
5915 hr = IStream_Release(stm);
5916 ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
5918 hr = IStorage_OpenStream(stg, stringpool, NULL, STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &stm);
5919 ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
5920 ok(stm != NULL, "Expected non-NULL stream\n");
5922 hr = IStream_Read(stm, data, MAX_PATH, &read);
5923 ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
5926 ok(read == 64, "Expected 64, got %d\n", read);
5927 ok(!memcmp(data, data13, read), "Unexpected data\n");
5930 hr = IStream_Release(stm);
5931 ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
5933 hr = IStorage_Release(stg);
5934 ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
5936 DeleteFileA(msifile);
5939 static void test_viewmodify_delete(void)
5941 MSIHANDLE hdb = 0, hview = 0, hrec = 0;
5947 DeleteFile(msifile);
5949 /* just MsiOpenDatabase should not create a file */
5950 r = MsiOpenDatabase(msifile, MSIDBOPEN_CREATE, &hdb);
5951 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5953 query = "CREATE TABLE `phone` ( "
5954 "`id` INT, `name` CHAR(32), `number` CHAR(32) "
5955 "PRIMARY KEY `id`)";
5956 r = run_query(hdb, 0, query);
5957 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5959 query = "INSERT INTO `phone` ( `id`, `name`, `number` )"
5960 "VALUES('1', 'Alan', '5030581')";
5961 r = run_query(hdb, 0, query);
5962 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5964 query = "INSERT INTO `phone` ( `id`, `name`, `number` )"
5965 "VALUES('2', 'Barry', '928440')";
5966 r = run_query(hdb, 0, query);
5967 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5969 query = "INSERT INTO `phone` ( `id`, `name`, `number` )"
5970 "VALUES('3', 'Cindy', '2937550')";
5971 r = run_query(hdb, 0, query);
5972 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5974 query = "SELECT * FROM `phone` WHERE `id` <= 2";
5975 r = MsiDatabaseOpenView(hdb, query, &hview);
5976 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5977 r = MsiViewExecute(hview, 0);
5978 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5979 r = MsiViewFetch(hview, &hrec);
5980 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5983 r = MsiViewModify(hview, MSIMODIFY_DELETE, hrec);
5984 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5986 r = MsiCloseHandle(hrec);
5987 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5988 r = MsiViewFetch(hview, &hrec);
5989 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5992 r = MsiViewModify(hview, MSIMODIFY_DELETE, hrec);
5993 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5995 r = MsiCloseHandle(hrec);
5996 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5997 r = MsiViewClose(hview);
5998 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5999 r = MsiCloseHandle(hview);
6000 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6002 query = "SELECT * FROM `phone`";
6003 r = MsiDatabaseOpenView(hdb, query, &hview);
6004 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6005 r = MsiViewExecute(hview, 0);
6006 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6007 r = MsiViewFetch(hview, &hrec);
6008 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6010 r = MsiRecordGetInteger(hrec, 1);
6011 ok(r == 3, "Expected 3, got %d\n", r);
6013 sz = sizeof(buffer);
6014 r = MsiRecordGetString(hrec, 2, buffer, &sz);
6015 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6016 ok(!lstrcmp(buffer, "Cindy"), "Expected Cindy, got %s\n", buffer);
6018 sz = sizeof(buffer);
6019 r = MsiRecordGetString(hrec, 3, buffer, &sz);
6020 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6021 ok(!lstrcmp(buffer, "2937550"), "Expected 2937550, got %s\n", buffer);
6023 r = MsiCloseHandle(hrec);
6024 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6026 r = MsiViewFetch(hview, &hrec);
6027 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
6029 r = MsiViewClose(hview);
6030 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6031 r = MsiCloseHandle(hview);
6032 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6033 r = MsiCloseHandle(hdb);
6034 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6037 static const WCHAR _Tables[] = {0x4840, 0x3f7f, 0x4164, 0x422f, 0x4836, 0};
6038 static const WCHAR _StringData[] = {0x4840, 0x3f3f, 0x4577, 0x446c, 0x3b6a, 0x45e4, 0x4824, 0};
6039 static const WCHAR _StringPool[] = {0x4840, 0x3f3f, 0x4577, 0x446c, 0x3e6a, 0x44b2, 0x482f, 0};
6041 static const WCHAR data14[] = { /* _StringPool */
6043 0, 0, /* string 0 '' */
6046 static const struct {
6050 } database_table_data[] =
6053 {_StringData, NULL, 0},
6054 {_StringPool, data14, sizeof data14},
6057 static void enum_stream_names(IStorage *stg)
6059 IEnumSTATSTG *stgenum = NULL;
6064 BYTE data[MAX_PATH];
6065 BYTE check[MAX_PATH];
6068 memset(check, 'a', MAX_PATH);
6070 hr = IStorage_EnumElements(stg, 0, NULL, 0, &stgenum);
6071 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
6077 hr = IEnumSTATSTG_Next(stgenum, 1, &stat, &count);
6078 if(FAILED(hr) || !count)
6081 ok(!lstrcmpW(stat.pwcsName, database_table_data[n].name),
6082 "Expected table %d name to match\n", n);
6085 hr = IStorage_OpenStream(stg, stat.pwcsName, NULL,
6086 STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &stm);
6087 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
6088 ok(stm != NULL, "Expected non-NULL stream\n");
6090 CoTaskMemFree(stat.pwcsName);
6093 memset(data, 'a', MAX_PATH);
6094 hr = IStream_Read(stm, data, sz, &count);
6095 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
6097 ok(count == database_table_data[n].size,
6098 "Expected %d, got %d\n", database_table_data[n].size, count);
6100 if (!database_table_data[n].size)
6101 ok(!memcmp(data, check, MAX_PATH), "data should not be changed\n");
6103 ok(!memcmp(data, database_table_data[n].data, database_table_data[n].size),
6104 "Expected table %d data to match\n", n);
6106 IStream_Release(stm);
6110 ok(n == 3, "Expected 3, got %d\n", n);
6112 IEnumSTATSTG_Release(stgenum);
6115 static void test_defaultdatabase(void)
6120 IStorage *stg = NULL;
6122 DeleteFile(msifile);
6124 r = MsiOpenDatabase(msifile, MSIDBOPEN_CREATE, &hdb);
6125 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6127 r = MsiDatabaseCommit(hdb);
6128 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6130 MsiCloseHandle(hdb);
6132 hr = StgOpenStorage(msifileW, NULL, STGM_READ | STGM_SHARE_DENY_WRITE, NULL, 0, &stg);
6133 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
6134 ok(stg != NULL, "Expected non-NULL stg\n");
6136 enum_stream_names(stg);
6138 IStorage_Release(stg);
6139 DeleteFileA(msifile);
6142 static void test_order(void)
6144 MSIHANDLE hdb, hview, hrec;
6145 CHAR buffer[MAX_PATH];
6151 ok(hdb, "failed to create db\n");
6153 query = "CREATE TABLE `Empty` ( `A` SHORT NOT NULL PRIMARY KEY `A`)";
6154 r = run_query(hdb, 0, query);
6155 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6157 query = "CREATE TABLE `Mesa` ( `A` SHORT NOT NULL, `B` SHORT, `C` SHORT PRIMARY KEY `A`)";
6158 r = run_query(hdb, 0, query);
6159 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6161 query = "INSERT INTO `Mesa` ( `A`, `B`, `C` ) VALUES ( 1, 2, 9 )";
6162 r = run_query(hdb, 0, query);
6163 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6165 query = "INSERT INTO `Mesa` ( `A`, `B`, `C` ) VALUES ( 3, 4, 7 )";
6166 r = run_query(hdb, 0, query);
6167 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6169 query = "INSERT INTO `Mesa` ( `A`, `B`, `C` ) VALUES ( 5, 6, 8 )";
6170 r = run_query(hdb, 0, query);
6171 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6173 query = "CREATE TABLE `Sideboard` ( `D` SHORT NOT NULL, `E` SHORT, `F` SHORT PRIMARY KEY `D`)";
6174 r = run_query(hdb, 0, query);
6175 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6177 query = "INSERT INTO `Sideboard` ( `D`, `E`, `F` ) VALUES ( 10, 11, 18 )";
6178 r = run_query(hdb, 0, query);
6179 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6181 query = "INSERT INTO `Sideboard` ( `D`, `E`, `F` ) VALUES ( 12, 13, 16 )";
6182 r = run_query(hdb, 0, query);
6183 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6185 query = "INSERT INTO `Sideboard` ( `D`, `E`, `F` ) VALUES ( 14, 15, 17 )";
6186 r = run_query(hdb, 0, query);
6187 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6189 query = "SELECT `A`, `B` FROM `Mesa` ORDER BY `C`";
6190 r = MsiDatabaseOpenView(hdb, query, &hview);
6191 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6192 r = MsiViewExecute(hview, 0);
6193 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6195 r = MsiViewFetch(hview, &hrec);
6196 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6198 val = MsiRecordGetInteger(hrec, 1);
6199 ok(val == 3, "Expected 3, got %d\n", val);
6201 val = MsiRecordGetInteger(hrec, 2);
6202 ok(val == 4, "Expected 3, got %d\n", val);
6204 MsiCloseHandle(hrec);
6206 r = MsiViewFetch(hview, &hrec);
6207 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6209 val = MsiRecordGetInteger(hrec, 1);
6210 ok(val == 5, "Expected 5, got %d\n", val);
6212 val = MsiRecordGetInteger(hrec, 2);
6213 ok(val == 6, "Expected 6, got %d\n", val);
6215 MsiCloseHandle(hrec);
6217 r = MsiViewFetch(hview, &hrec);
6218 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6220 val = MsiRecordGetInteger(hrec, 1);
6221 ok(val == 1, "Expected 1, got %d\n", val);
6223 val = MsiRecordGetInteger(hrec, 2);
6224 ok(val == 2, "Expected 2, got %d\n", val);
6226 MsiCloseHandle(hrec);
6228 r = MsiViewFetch(hview, &hrec);
6229 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
6231 MsiViewClose(hview);
6232 MsiCloseHandle(hview);
6234 query = "SELECT `A`, `D` FROM `Mesa`, `Sideboard` ORDER BY `F`";
6235 r = MsiDatabaseOpenView(hdb, query, &hview);
6236 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6237 r = MsiViewExecute(hview, 0);
6238 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6240 r = MsiViewFetch(hview, &hrec);
6241 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6243 val = MsiRecordGetInteger(hrec, 1);
6244 ok(val == 1, "Expected 1, got %d\n", val);
6246 val = MsiRecordGetInteger(hrec, 2);
6247 ok(val == 12, "Expected 12, got %d\n", val);
6249 MsiCloseHandle(hrec);
6251 r = MsiViewFetch(hview, &hrec);
6252 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6254 val = MsiRecordGetInteger(hrec, 1);
6255 ok(val == 3, "Expected 3, got %d\n", val);
6257 val = MsiRecordGetInteger(hrec, 2);
6258 ok(val == 12, "Expected 12, got %d\n", val);
6260 MsiCloseHandle(hrec);
6262 r = MsiViewFetch(hview, &hrec);
6263 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6265 val = MsiRecordGetInteger(hrec, 1);
6266 ok(val == 5, "Expected 5, got %d\n", val);
6268 val = MsiRecordGetInteger(hrec, 2);
6269 ok(val == 12, "Expected 12, got %d\n", val);
6271 MsiCloseHandle(hrec);
6273 r = MsiViewFetch(hview, &hrec);
6274 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6276 val = MsiRecordGetInteger(hrec, 1);
6277 ok(val == 1, "Expected 1, got %d\n", val);
6279 val = MsiRecordGetInteger(hrec, 2);
6280 ok(val == 14, "Expected 14, got %d\n", val);
6282 MsiCloseHandle(hrec);
6284 r = MsiViewFetch(hview, &hrec);
6285 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6287 val = MsiRecordGetInteger(hrec, 1);
6288 ok(val == 3, "Expected 3, got %d\n", val);
6290 val = MsiRecordGetInteger(hrec, 2);
6291 ok(val == 14, "Expected 14, got %d\n", val);
6293 MsiCloseHandle(hrec);
6295 r = MsiViewFetch(hview, &hrec);
6296 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6298 val = MsiRecordGetInteger(hrec, 1);
6299 ok(val == 5, "Expected 5, got %d\n", val);
6301 val = MsiRecordGetInteger(hrec, 2);
6302 ok(val == 14, "Expected 14, got %d\n", val);
6304 MsiCloseHandle(hrec);
6306 r = MsiViewFetch(hview, &hrec);
6307 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6309 val = MsiRecordGetInteger(hrec, 1);
6310 ok(val == 1, "Expected 1, got %d\n", val);
6312 val = MsiRecordGetInteger(hrec, 2);
6313 ok(val == 10, "Expected 10, got %d\n", val);
6315 MsiCloseHandle(hrec);
6317 r = MsiViewFetch(hview, &hrec);
6318 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6320 val = MsiRecordGetInteger(hrec, 1);
6321 ok(val == 3, "Expected 3, got %d\n", val);
6323 val = MsiRecordGetInteger(hrec, 2);
6324 ok(val == 10, "Expected 10, got %d\n", val);
6326 MsiCloseHandle(hrec);
6328 r = MsiViewFetch(hview, &hrec);
6329 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6331 val = MsiRecordGetInteger(hrec, 1);
6332 ok(val == 5, "Expected 5, got %d\n", val);
6334 val = MsiRecordGetInteger(hrec, 2);
6335 ok(val == 10, "Expected 10, got %d\n", val);
6337 MsiCloseHandle(hrec);
6339 r = MsiViewFetch(hview, &hrec);
6340 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
6342 MsiViewClose(hview);
6343 MsiCloseHandle(hview);
6345 query = "SELECT * FROM `Empty` ORDER BY `A`";
6346 r = MsiDatabaseOpenView(hdb, query, &hview);
6347 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6348 r = MsiViewExecute(hview, 0);
6349 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6351 r = MsiViewFetch(hview, &hrec);
6352 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
6354 MsiViewClose(hview);
6355 MsiCloseHandle(hview);
6357 query = "CREATE TABLE `Buffet` ( `One` CHAR(72), `Two` SHORT PRIMARY KEY `One`)";
6358 r = run_query(hdb, 0, query);
6359 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6361 query = "INSERT INTO `Buffet` ( `One`, `Two` ) VALUES ( 'uno', 2)";
6362 r = run_query(hdb, 0, query);
6363 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6365 query = "INSERT INTO `Buffet` ( `One`, `Two` ) VALUES ( 'dos', 3)";
6366 r = run_query(hdb, 0, query);
6367 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6369 query = "INSERT INTO `Buffet` ( `One`, `Two` ) VALUES ( 'tres', 1)";
6370 r = run_query(hdb, 0, query);
6371 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6373 query = "SELECT * FROM `Buffet` WHERE `One` = 'dos' ORDER BY `Two`";
6374 r = MsiDatabaseOpenView(hdb, query, &hview);
6375 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6376 r = MsiViewExecute(hview, 0);
6377 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6379 r = MsiViewFetch(hview, &hrec);
6380 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6382 sz = sizeof(buffer);
6383 r = MsiRecordGetString(hrec, 1, buffer, &sz);
6384 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6385 ok(!lstrcmp(buffer, "dos"), "Expected \"dos\", got \"%s\"\n", buffer);
6387 r = MsiRecordGetInteger(hrec, 2);
6388 ok(r == 3, "Expected 3, got %d\n", r);
6390 MsiCloseHandle(hrec);
6392 r = MsiViewFetch(hview, &hrec);
6393 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
6395 MsiViewClose(hview);
6396 MsiCloseHandle(hview);
6397 MsiCloseHandle(hdb);
6400 static void test_viewmodify_delete_temporary(void)
6402 MSIHANDLE hdb, hview, hrec;
6406 DeleteFile(msifile);
6408 r = MsiOpenDatabase(msifile, MSIDBOPEN_CREATE, &hdb);
6409 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6411 query = "CREATE TABLE `Table` ( `A` SHORT PRIMARY KEY `A` )";
6412 r = run_query(hdb, 0, query);
6413 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6415 query = "SELECT * FROM `Table`";
6416 r = MsiDatabaseOpenView(hdb, query, &hview);
6417 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6418 r = MsiViewExecute(hview, 0);
6419 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6421 hrec = MsiCreateRecord(1);
6422 MsiRecordSetInteger(hrec, 1, 1);
6424 r = MsiViewModify(hview, MSIMODIFY_INSERT, hrec);
6425 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6427 MsiCloseHandle(hrec);
6429 hrec = MsiCreateRecord(1);
6430 MsiRecordSetInteger(hrec, 1, 2);
6432 r = MsiViewModify(hview, MSIMODIFY_INSERT_TEMPORARY, hrec);
6433 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6435 MsiCloseHandle(hrec);
6437 hrec = MsiCreateRecord(1);
6438 MsiRecordSetInteger(hrec, 1, 3);
6440 r = MsiViewModify(hview, MSIMODIFY_INSERT, hrec);
6441 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6443 MsiCloseHandle(hrec);
6445 hrec = MsiCreateRecord(1);
6446 MsiRecordSetInteger(hrec, 1, 4);
6448 r = MsiViewModify(hview, MSIMODIFY_INSERT_TEMPORARY, hrec);
6449 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6451 MsiCloseHandle(hrec);
6452 MsiViewClose(hview);
6453 MsiCloseHandle(hview);
6455 query = "SELECT * FROM `Table` WHERE `A` = 2";
6456 r = MsiDatabaseOpenView(hdb, query, &hview);
6457 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6458 r = MsiViewExecute(hview, 0);
6459 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6460 r = MsiViewFetch(hview, &hrec);
6461 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6463 r = MsiViewModify(hview, MSIMODIFY_DELETE, hrec);
6464 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6466 MsiCloseHandle(hrec);
6467 MsiViewClose(hview);
6468 MsiCloseHandle(hview);
6470 query = "SELECT * FROM `Table` WHERE `A` = 3";
6471 r = MsiDatabaseOpenView(hdb, query, &hview);
6472 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6473 r = MsiViewExecute(hview, 0);
6474 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6475 r = MsiViewFetch(hview, &hrec);
6476 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6478 r = MsiViewModify(hview, MSIMODIFY_DELETE, hrec);
6479 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6481 MsiCloseHandle(hrec);
6482 MsiViewClose(hview);
6483 MsiCloseHandle(hview);
6485 query = "SELECT * FROM `Table` ORDER BY `A`";
6486 r = MsiDatabaseOpenView(hdb, query, &hview);
6487 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6488 r = MsiViewExecute(hview, 0);
6489 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6491 r = MsiViewFetch(hview, &hrec);
6492 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6494 r = MsiRecordGetInteger(hrec, 1);
6495 ok(r == 1, "Expected 1, got %d\n", r);
6497 MsiCloseHandle(hrec);
6499 r = MsiViewFetch(hview, &hrec);
6500 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6502 r = MsiRecordGetInteger(hrec, 1);
6503 ok(r == 4, "Expected 4, got %d\n", r);
6505 MsiCloseHandle(hrec);
6507 r = MsiViewFetch(hview, &hrec);
6508 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
6510 MsiViewClose(hview);
6511 MsiCloseHandle(hview);
6512 MsiCloseHandle(hdb);
6513 DeleteFileA(msifile);
6516 static void test_deleterow(void)
6518 MSIHANDLE hdb, hview, hrec;
6524 DeleteFile(msifile);
6526 r = MsiOpenDatabase(msifile, MSIDBOPEN_CREATE, &hdb);
6527 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6529 query = "CREATE TABLE `Table` ( `A` CHAR(72) NOT NULL PRIMARY KEY `A` )";
6530 r = run_query(hdb, 0, query);
6531 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6533 query = "INSERT INTO `Table` (`A`) VALUES ('one')";
6534 r = run_query(hdb, 0, query);
6535 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6537 query = "INSERT INTO `Table` (`A`) VALUES ('two')";
6538 r = run_query(hdb, 0, query);
6539 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6541 query = "DELETE FROM `Table` WHERE `A` = 'one'";
6542 r = run_query(hdb, 0, query);
6543 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6545 r = MsiDatabaseCommit(hdb);
6546 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6548 MsiCloseHandle(hdb);
6550 r = MsiOpenDatabase(msifile, MSIDBOPEN_READONLY, &hdb);
6551 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6553 query = "SELECT * FROM `Table`";
6554 r = MsiDatabaseOpenView(hdb, query, &hview);
6555 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6556 r = MsiViewExecute(hview, 0);
6557 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6559 r = MsiViewFetch(hview, &hrec);
6560 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6563 r = MsiRecordGetStringA(hrec, 1, buf, &size);
6564 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6565 ok(!lstrcmpA(buf, "two"), "Expected two, got %s\n", buf);
6567 MsiCloseHandle(hrec);
6569 r = MsiViewFetch(hview, &hrec);
6570 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
6572 MsiViewClose(hview);
6573 MsiCloseHandle(hview);
6574 MsiCloseHandle(hdb);
6575 DeleteFileA(msifile);
6578 static const CHAR import_dat[] = "A\n"
6581 "This is a new 'string' ok\n";
6583 static void test_quotes(void)
6585 MSIHANDLE hdb, hview, hrec;
6591 DeleteFile(msifile);
6593 r = MsiOpenDatabase(msifile, MSIDBOPEN_CREATE, &hdb);
6594 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6596 query = "CREATE TABLE `Table` ( `A` CHAR(72) NOT NULL PRIMARY KEY `A` )";
6597 r = run_query(hdb, 0, query);
6598 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6600 query = "INSERT INTO `Table` ( `A` ) VALUES ( 'This is a 'string' ok' )";
6601 r = run_query(hdb, 0, query);
6602 ok(r == ERROR_BAD_QUERY_SYNTAX,
6603 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
6605 query = "INSERT INTO `Table` ( `A` ) VALUES ( \"This is a 'string' ok\" )";
6606 r = run_query(hdb, 0, query);
6607 ok(r == ERROR_BAD_QUERY_SYNTAX,
6608 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
6610 query = "INSERT INTO `Table` ( `A` ) VALUES ( \"test\" )";
6611 r = run_query(hdb, 0, query);
6612 ok(r == ERROR_BAD_QUERY_SYNTAX,
6613 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
6615 query = "INSERT INTO `Table` ( `A` ) VALUES ( 'This is a ''string'' ok' )";
6616 r = run_query(hdb, 0, query);
6617 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
6619 query = "INSERT INTO `Table` ( `A` ) VALUES ( 'This is a '''string''' ok' )";
6620 r = run_query(hdb, 0, query);
6621 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
6623 query = "INSERT INTO `Table` ( `A` ) VALUES ( 'This is a \'string\' ok' )";
6624 r = run_query(hdb, 0, query);
6625 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
6627 query = "INSERT INTO `Table` ( `A` ) VALUES ( 'This is a \"string\" ok' )";
6628 r = run_query(hdb, 0, query);
6629 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6631 query = "SELECT * FROM `Table`";
6632 r = MsiDatabaseOpenView(hdb, query, &hview);
6633 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6635 r = MsiViewExecute(hview, 0);
6636 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6638 r = MsiViewFetch(hview, &hrec);
6639 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6642 r = MsiRecordGetString(hrec, 1, buf, &size);
6643 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6644 ok(!lstrcmp(buf, "This is a \"string\" ok"),
6645 "Expected \"This is a \"string\" ok\", got %s\n", buf);
6647 MsiCloseHandle(hrec);
6649 r = MsiViewFetch(hview, &hrec);
6650 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
6652 MsiViewClose(hview);
6653 MsiCloseHandle(hview);
6655 write_file("import.idt", import_dat, (sizeof(import_dat) - 1) * sizeof(char));
6657 r = MsiDatabaseImportA(hdb, CURR_DIR, "import.idt");
6658 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6660 DeleteFileA("import.idt");
6662 query = "SELECT * FROM `Table`";
6663 r = MsiDatabaseOpenView(hdb, query, &hview);
6664 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6666 r = MsiViewExecute(hview, 0);
6667 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6669 r = MsiViewFetch(hview, &hrec);
6670 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6673 r = MsiRecordGetString(hrec, 1, buf, &size);
6674 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6675 ok(!lstrcmp(buf, "This is a new 'string' ok"),
6676 "Expected \"This is a new 'string' ok\", got %s\n", buf);
6678 MsiCloseHandle(hrec);
6680 r = MsiViewFetch(hview, &hrec);
6681 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
6683 MsiViewClose(hview);
6684 MsiCloseHandle(hview);
6685 MsiCloseHandle(hdb);
6686 DeleteFileA(msifile);
6689 static void test_carriagereturn(void)
6691 MSIHANDLE hdb, hview, hrec;
6697 DeleteFile(msifile);
6699 r = MsiOpenDatabase(msifile, MSIDBOPEN_CREATE, &hdb);
6700 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6702 query = "CREATE TABLE `Table`\r ( `A` CHAR(72) NOT NULL PRIMARY KEY `A` )";
6703 r = run_query(hdb, 0, query);
6704 ok(r == ERROR_BAD_QUERY_SYNTAX,
6705 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
6707 query = "CREATE TABLE `Table` \r( `A` CHAR(72) NOT NULL PRIMARY KEY `A` )";
6708 r = run_query(hdb, 0, query);
6709 ok(r == ERROR_BAD_QUERY_SYNTAX,
6710 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
6712 query = "CREATE\r TABLE `Table` ( `A` CHAR(72) NOT NULL PRIMARY KEY `A` )";
6713 r = run_query(hdb, 0, query);
6714 ok(r == ERROR_BAD_QUERY_SYNTAX,
6715 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
6717 query = "CREATE TABLE\r `Table` ( `A` CHAR(72) NOT NULL PRIMARY KEY `A` )";
6718 r = run_query(hdb, 0, query);
6719 ok(r == ERROR_BAD_QUERY_SYNTAX,
6720 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
6722 query = "CREATE TABLE `Table` (\r `A` CHAR(72) NOT NULL PRIMARY KEY `A` )";
6723 r = run_query(hdb, 0, query);
6724 ok(r == ERROR_BAD_QUERY_SYNTAX,
6725 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
6727 query = "CREATE TABLE `Table` ( `A`\r CHAR(72) NOT NULL PRIMARY KEY `A` )";
6728 r = run_query(hdb, 0, query);
6729 ok(r == ERROR_BAD_QUERY_SYNTAX,
6730 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
6732 query = "CREATE TABLE `Table` ( `A` CHAR(72)\r NOT NULL PRIMARY KEY `A` )";
6733 r = run_query(hdb, 0, query);
6734 ok(r == ERROR_BAD_QUERY_SYNTAX,
6735 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
6737 query = "CREATE TABLE `Table` ( `A` CHAR(72) NOT\r NULL PRIMARY KEY `A` )";
6738 r = run_query(hdb, 0, query);
6739 ok(r == ERROR_BAD_QUERY_SYNTAX,
6740 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
6742 query = "CREATE TABLE `Table` ( `A` CHAR(72) NOT \rNULL PRIMARY KEY `A` )";
6743 r = run_query(hdb, 0, query);
6744 ok(r == ERROR_BAD_QUERY_SYNTAX,
6745 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
6747 query = "CREATE TABLE `Table` ( `A` CHAR(72) NOT NULL\r PRIMARY KEY `A` )";
6748 r = run_query(hdb, 0, query);
6749 ok(r == ERROR_BAD_QUERY_SYNTAX,
6750 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
6752 query = "CREATE TABLE `Table` ( `A` CHAR(72) NOT NULL \rPRIMARY KEY `A` )";
6753 r = run_query(hdb, 0, query);
6754 ok(r == ERROR_BAD_QUERY_SYNTAX,
6755 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
6757 query = "CREATE TABLE `Table` ( `A` CHAR(72) NOT NULL PRIMARY\r KEY `A` )";
6758 r = run_query(hdb, 0, query);
6759 ok(r == ERROR_BAD_QUERY_SYNTAX,
6760 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
6762 query = "CREATE TABLE `Table` ( `A` CHAR(72) NOT NULL PRIMARY \rKEY `A` )";
6763 r = run_query(hdb, 0, query);
6764 ok(r == ERROR_BAD_QUERY_SYNTAX,
6765 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
6767 query = "CREATE TABLE `Table` ( `A` CHAR(72) NOT NULL PRIMARY KEY\r `A` )";
6768 r = run_query(hdb, 0, query);
6769 ok(r == ERROR_BAD_QUERY_SYNTAX,
6770 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
6772 query = "CREATE TABLE `Table` ( `A` CHAR(72) NOT NULL PRIMARY KEY `A`\r )";
6773 r = run_query(hdb, 0, query);
6774 ok(r == ERROR_BAD_QUERY_SYNTAX,
6775 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
6777 query = "CREATE TABLE `Table` ( `A` CHAR(72) NOT NULL PRIMARY KEY `A` )\r";
6778 r = run_query(hdb, 0, query);
6779 ok(r == ERROR_BAD_QUERY_SYNTAX,
6780 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
6782 query = "CREATE TABLE `\rOne` ( `A` CHAR(72) NOT NULL PRIMARY KEY `A` )";
6783 r = run_query(hdb, 0, query);
6784 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6786 query = "CREATE TABLE `Tw\ro` ( `A` CHAR(72) NOT NULL PRIMARY KEY `A` )";
6787 r = run_query(hdb, 0, query);
6788 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6790 query = "CREATE TABLE `Three\r` ( `A` CHAR(72) NOT NULL PRIMARY KEY `A` )";
6791 r = run_query(hdb, 0, query);
6792 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6794 query = "CREATE TABLE `Four` ( `A\r` CHAR(72) NOT NULL PRIMARY KEY `A` )";
6795 r = run_query(hdb, 0, query);
6796 ok(r == ERROR_BAD_QUERY_SYNTAX,
6797 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
6799 query = "CREATE TABLE `Four` ( `\rA` CHAR(72) NOT NULL PRIMARY KEY `A` )";
6800 r = run_query(hdb, 0, query);
6801 ok(r == ERROR_BAD_QUERY_SYNTAX,
6802 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
6804 query = "CREATE TABLE `Four` ( `A` CHAR(72\r) NOT NULL PRIMARY KEY `A` )";
6805 r = run_query(hdb, 0, query);
6806 ok(r == ERROR_BAD_QUERY_SYNTAX,
6807 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
6809 query = "CREATE TABLE `Four` ( `A` CHAR(\r72) NOT NULL PRIMARY KEY `A` )";
6810 r = run_query(hdb, 0, query);
6811 ok(r == ERROR_BAD_QUERY_SYNTAX,
6812 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
6814 query = "CREATE TABLE `Four` ( `A` CHAR(72) NOT NULL PRIMARY KEY `\rA` )";
6815 r = run_query(hdb, 0, query);
6816 ok(r == ERROR_BAD_QUERY_SYNTAX,
6817 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
6819 query = "CREATE TABLE `Four` ( `A` CHAR(72) NOT NULL PRIMARY KEY `A\r` )";
6820 r = run_query(hdb, 0, query);
6821 ok(r == ERROR_BAD_QUERY_SYNTAX,
6822 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
6824 query = "CREATE TABLE `Four` ( `A` CHAR(72) NOT NULL PRIMARY KEY `A\r` )";
6825 r = run_query(hdb, 0, query);
6826 ok(r == ERROR_BAD_QUERY_SYNTAX,
6827 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
6829 query = "SELECT * FROM `_Tables`";
6830 r = MsiDatabaseOpenView(hdb, query, &hview);
6831 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6832 r = MsiViewExecute(hview, 0);
6833 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6835 r = MsiViewFetch(hview, &hrec);
6836 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6839 r = MsiRecordGetStringA(hrec, 1, buf, &size);
6840 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6841 ok(!lstrcmpA(buf, "\rOne"), "Expected \"\\rOne\", got \"%s\"\n", buf);
6843 MsiCloseHandle(hrec);
6845 r = MsiViewFetch(hview, &hrec);
6846 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6849 r = MsiRecordGetStringA(hrec, 1, buf, &size);
6850 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6851 ok(!lstrcmpA(buf, "Tw\ro"), "Expected \"Tw\\ro\", got \"%s\"\n", buf);
6853 MsiCloseHandle(hrec);
6855 r = MsiViewFetch(hview, &hrec);
6856 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6859 r = MsiRecordGetStringA(hrec, 1, buf, &size);
6860 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6861 ok(!lstrcmpA(buf, "Three\r"), "Expected \"Three\r\", got \"%s\"\n", buf);
6863 MsiCloseHandle(hrec);
6865 r = MsiViewFetch(hview, &hrec);
6866 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
6868 MsiViewClose(hview);
6869 MsiCloseHandle(hview);
6871 MsiCloseHandle(hdb);
6872 DeleteFileA(msifile);
6875 static void test_noquotes(void)
6877 MSIHANDLE hdb, hview, hrec;
6883 DeleteFile(msifile);
6885 r = MsiOpenDatabase(msifile, MSIDBOPEN_CREATE, &hdb);
6886 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6888 query = "CREATE TABLE Table ( `A` CHAR(72) NOT NULL PRIMARY KEY `A` )";
6889 r = run_query(hdb, 0, query);
6890 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
6892 query = "CREATE TABLE `Table` ( A CHAR(72) NOT NULL PRIMARY KEY `A` )";
6893 r = run_query(hdb, 0, query);
6894 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6896 query = "CREATE TABLE `Table2` ( `A` CHAR(72) NOT NULL PRIMARY KEY A )";
6897 r = run_query(hdb, 0, query);
6898 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6900 query = "CREATE TABLE `Table3` ( A CHAR(72) NOT NULL PRIMARY KEY A )";
6901 r = run_query(hdb, 0, query);
6902 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6904 query = "SELECT * FROM `_Tables`";
6905 r = MsiDatabaseOpenView(hdb, query, &hview);
6906 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6907 r = MsiViewExecute(hview, 0);
6908 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6910 r = MsiViewFetch(hview, &hrec);
6911 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6914 r = MsiRecordGetStringA(hrec, 1, buf, &size);
6915 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6916 ok(!lstrcmpA(buf, "Table"), "Expected \"Table\", got \"%s\"\n", buf);
6918 MsiCloseHandle(hrec);
6920 r = MsiViewFetch(hview, &hrec);
6921 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6924 r = MsiRecordGetStringA(hrec, 1, buf, &size);
6925 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6926 ok(!lstrcmpA(buf, "Table2"), "Expected \"Table2\", got \"%s\"\n", buf);
6928 MsiCloseHandle(hrec);
6930 r = MsiViewFetch(hview, &hrec);
6931 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6934 r = MsiRecordGetStringA(hrec, 1, buf, &size);
6935 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6936 ok(!lstrcmpA(buf, "Table3"), "Expected \"Table3\", got \"%s\"\n", buf);
6938 MsiCloseHandle(hrec);
6940 r = MsiViewFetch(hview, &hrec);
6941 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
6943 MsiViewClose(hview);
6944 MsiCloseHandle(hview);
6946 query = "SELECT * FROM `_Columns`";
6947 r = MsiDatabaseOpenView(hdb, query, &hview);
6948 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6949 r = MsiViewExecute(hview, 0);
6950 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6952 r = MsiViewFetch(hview, &hrec);
6953 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6956 r = MsiRecordGetStringA(hrec, 1, buf, &size);
6957 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6958 ok(!lstrcmpA(buf, "Table"), "Expected \"Table\", got \"%s\"\n", buf);
6960 r = MsiRecordGetInteger(hrec, 2);
6961 ok(r == 1, "Expected 1, got %d\n", r);
6964 r = MsiRecordGetStringA(hrec, 3, buf, &size);
6965 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6966 ok(!lstrcmpA(buf, "A"), "Expected \"A\", got \"%s\"\n", buf);
6968 MsiCloseHandle(hrec);
6970 r = MsiViewFetch(hview, &hrec);
6971 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6974 r = MsiRecordGetStringA(hrec, 1, buf, &size);
6975 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6976 ok(!lstrcmpA(buf, "Table2"), "Expected \"Table2\", got \"%s\"\n", buf);
6978 r = MsiRecordGetInteger(hrec, 2);
6979 ok(r == 1, "Expected 1, got %d\n", r);
6982 r = MsiRecordGetStringA(hrec, 3, buf, &size);
6983 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6984 ok(!lstrcmpA(buf, "A"), "Expected \"A\", got \"%s\"\n", buf);
6986 MsiCloseHandle(hrec);
6988 r = MsiViewFetch(hview, &hrec);
6989 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6992 r = MsiRecordGetStringA(hrec, 1, buf, &size);
6993 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6994 ok(!lstrcmpA(buf, "Table3"), "Expected \"Table3\", got \"%s\"\n", buf);
6996 r = MsiRecordGetInteger(hrec, 2);
6997 ok(r == 1, "Expected 1, got %d\n", r);
7000 r = MsiRecordGetStringA(hrec, 3, buf, &size);
7001 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7002 ok(!lstrcmpA(buf, "A"), "Expected \"A\", got \"%s\"\n", buf);
7004 MsiCloseHandle(hrec);
7006 r = MsiViewFetch(hview, &hrec);
7007 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
7009 MsiViewClose(hview);
7010 MsiCloseHandle(hview);
7012 query = "INSERT INTO Table ( `A` ) VALUES ( 'hi' )";
7013 r = run_query(hdb, 0, query);
7014 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
7016 query = "INSERT INTO `Table` ( A ) VALUES ( 'hi' )";
7017 r = run_query(hdb, 0, query);
7018 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7020 query = "INSERT INTO `Table` ( `A` ) VALUES ( hi )";
7021 r = run_query(hdb, 0, query);
7022 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
7024 query = "SELECT * FROM Table WHERE `A` = 'hi'";
7025 r = run_query(hdb, 0, query);
7026 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
7028 query = "SELECT * FROM `Table` WHERE `A` = hi";
7029 r = run_query(hdb, 0, query);
7030 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
7032 query = "SELECT * FROM Table";
7033 r = run_query(hdb, 0, query);
7034 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
7036 query = "SELECT * FROM Table2";
7037 r = MsiDatabaseOpenView(hdb, query, &hview);
7038 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7039 r = MsiViewExecute(hview, 0);
7040 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7042 r = MsiViewFetch(hview, &hrec);
7043 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
7045 MsiViewClose(hview);
7046 MsiCloseHandle(hview);
7048 query = "SELECT * FROM `Table` WHERE A = 'hi'";
7049 r = MsiDatabaseOpenView(hdb, query, &hview);
7050 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7051 r = MsiViewExecute(hview, 0);
7052 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7054 r = MsiViewFetch(hview, &hrec);
7055 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7058 r = MsiRecordGetStringA(hrec, 1, buf, &size);
7059 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7060 ok(!lstrcmpA(buf, "hi"), "Expected \"hi\", got \"%s\"\n", buf);
7062 MsiCloseHandle(hrec);
7064 r = MsiViewFetch(hview, &hrec);
7065 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
7067 MsiViewClose(hview);
7068 MsiCloseHandle(hview);
7069 MsiCloseHandle(hdb);
7070 DeleteFileA(msifile);
7073 static void read_file_data(LPCSTR filename, LPSTR buffer)
7078 file = CreateFileA( filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL );
7079 ZeroMemory(buffer, MAX_PATH);
7080 ReadFile(file, buffer, MAX_PATH, &read, NULL);
7084 static void test_forcecodepage(void)
7088 char buffer[MAX_PATH];
7091 DeleteFile(msifile);
7092 GetCurrentDirectoryA(MAX_PATH, CURR_DIR);
7094 r = MsiOpenDatabase(msifile, MSIDBOPEN_CREATE, &hdb);
7095 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7097 query = "SELECT * FROM `_ForceCodepage`";
7098 r = run_query(hdb, 0, query);
7099 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
7101 query = "CREATE TABLE `Table` ( `A` CHAR(72) NOT NULL PRIMARY KEY `A` )";
7102 r = run_query(hdb, 0, query);
7103 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7105 query = "SELECT * FROM `_ForceCodepage`";
7106 r = run_query(hdb, 0, query);
7107 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
7109 r = MsiDatabaseCommit(hdb);
7110 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7112 query = "SELECT * FROM `_ForceCodepage`";
7113 r = run_query(hdb, 0, query);
7114 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
7116 MsiCloseHandle(hdb);
7118 r = MsiOpenDatabase(msifile, MSIDBOPEN_DIRECT, &hdb);
7119 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7121 query = "SELECT * FROM `_ForceCodepage`";
7122 r = run_query(hdb, 0, query);
7123 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
7125 r = MsiDatabaseExport(hdb, "_ForceCodepage", CURR_DIR, "forcecodepage.idt");
7126 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7128 read_file_data("forcecodepage.idt", buffer);
7129 ok(!lstrcmpA(buffer, "\r\n\r\n0\t_ForceCodepage\r\n"),
7130 "Expected \"\r\n\r\n0\t_ForceCodepage\r\n\", got \"%s\"\n", buffer);
7132 create_file_data("forcecodepage.idt", "\r\n\r\n850\t_ForceCodepage\r\n", 0);
7134 r = MsiDatabaseImportA(hdb, CURR_DIR, "forcecodepage.idt");
7135 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7137 r = MsiDatabaseExport(hdb, "_ForceCodepage", CURR_DIR, "forcecodepage.idt");
7138 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7140 read_file_data("forcecodepage.idt", buffer);
7141 ok(!lstrcmpA(buffer, "\r\n\r\n850\t_ForceCodepage\r\n"),
7142 "Expected \"\r\n\r\n850\t_ForceCodepage\r\n\", got \"%s\"\n", buffer);
7144 create_file_data("forcecodepage.idt", "\r\n\r\n9999\t_ForceCodepage\r\n", 0);
7146 r = MsiDatabaseImportA(hdb, CURR_DIR, "forcecodepage.idt");
7147 ok(r == ERROR_FUNCTION_FAILED, "Expected ERROR_SUCCESS, got %d\n", r);
7149 MsiCloseHandle(hdb);
7150 DeleteFileA(msifile);
7151 DeleteFileA("forcecodepage.idt");
7154 static void test_viewmodify_refresh(void)
7156 MSIHANDLE hdb, hview, hrec;
7158 char buffer[MAX_PATH];
7162 DeleteFile(msifile);
7164 r = MsiOpenDatabase(msifile, MSIDBOPEN_CREATE, &hdb);
7165 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7167 query = "CREATE TABLE `Table` ( `A` CHAR(72) NOT NULL, `B` INT PRIMARY KEY `A` )";
7168 r = run_query(hdb, 0, query);
7169 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7171 query = "INSERT INTO `Table` ( `A`, `B` ) VALUES ( 'hi', 1 )";
7172 r = run_query(hdb, 0, query);
7173 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7175 query = "SELECT * FROM `Table`";
7176 r = MsiDatabaseOpenView(hdb, query, &hview);
7177 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7178 r = MsiViewExecute(hview, 0);
7179 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7181 r = MsiViewFetch(hview, &hrec);
7182 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7184 query = "UPDATE `Table` SET `B` = 2 WHERE `A` = 'hi'";
7185 r = run_query(hdb, 0, query);
7186 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7188 r = MsiViewModify(hview, MSIMODIFY_REFRESH, hrec);
7189 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7192 r = MsiRecordGetStringA(hrec, 1, buffer, &size);
7193 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7194 ok(!lstrcmpA(buffer, "hi"), "Expected \"hi\", got \"%s\"\n", buffer);
7195 ok(size == 2, "Expected 2, got %d\n", size);
7197 r = MsiRecordGetInteger(hrec, 2);
7198 ok(r == 2, "Expected 2, got %d\n", r);
7200 MsiCloseHandle(hrec);
7201 MsiViewClose(hview);
7202 MsiCloseHandle(hview);
7204 query = "INSERT INTO `Table` ( `A`, `B` ) VALUES ( 'hello', 3 )";
7205 r = run_query(hdb, 0, query);
7206 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7208 query = "SELECT * FROM `Table` WHERE `B` = 3";
7209 r = MsiDatabaseOpenView(hdb, query, &hview);
7210 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7211 r = MsiViewExecute(hview, 0);
7212 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7214 r = MsiViewFetch(hview, &hrec);
7215 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7217 query = "UPDATE `Table` SET `B` = 2 WHERE `A` = 'hello'";
7218 r = run_query(hdb, 0, query);
7219 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7221 query = "INSERT INTO `Table` ( `A`, `B` ) VALUES ( 'hithere', 3 )";
7222 r = run_query(hdb, 0, query);
7223 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7225 r = MsiViewModify(hview, MSIMODIFY_REFRESH, hrec);
7226 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7229 r = MsiRecordGetStringA(hrec, 1, buffer, &size);
7230 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7231 ok(!lstrcmpA(buffer, "hello"), "Expected \"hello\", got \"%s\"\n", buffer);
7232 ok(size == 5, "Expected 5, got %d\n", size);
7234 r = MsiRecordGetInteger(hrec, 2);
7235 ok(r == 2, "Expected 2, got %d\n", r);
7237 MsiCloseHandle(hrec);
7238 MsiViewClose(hview);
7239 MsiCloseHandle(hview);
7240 MsiCloseHandle(hdb);
7241 DeleteFileA(msifile);
7244 static void test_where_viewmodify(void)
7246 MSIHANDLE hdb, hview, hrec;
7250 DeleteFile(msifile);
7252 r = MsiOpenDatabase(msifile, MSIDBOPEN_CREATE, &hdb);
7253 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7255 query = "CREATE TABLE `Table` ( `A` INT, `B` INT PRIMARY KEY `A` )";
7256 r = run_query(hdb, 0, query);
7257 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7259 query = "INSERT INTO `Table` ( `A`, `B` ) VALUES ( 1, 2 )";
7260 r = run_query(hdb, 0, query);
7261 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7263 query = "INSERT INTO `Table` ( `A`, `B` ) VALUES ( 3, 4 )";
7264 r = run_query(hdb, 0, query);
7265 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7267 query = "INSERT INTO `Table` ( `A`, `B` ) VALUES ( 5, 6 )";
7268 r = run_query(hdb, 0, query);
7269 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7271 /* `B` = 3 doesn't match, but the view shouldn't be executed */
7272 query = "SELECT * FROM `Table` WHERE `B` = 3";
7273 r = MsiDatabaseOpenView(hdb, query, &hview);
7274 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7276 hrec = MsiCreateRecord(2);
7277 MsiRecordSetInteger(hrec, 1, 7);
7278 MsiRecordSetInteger(hrec, 2, 8);
7280 r = MsiViewModify(hview, MSIMODIFY_INSERT_TEMPORARY, hrec);
7281 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7283 MsiCloseHandle(hrec);
7284 MsiViewClose(hview);
7285 MsiCloseHandle(hview);
7287 query = "SELECT * FROM `Table` WHERE `A` = 7";
7288 r = MsiDatabaseOpenView(hdb, query, &hview);
7289 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7290 r = MsiViewExecute(hview, 0);
7291 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7293 r = MsiViewFetch(hview, &hrec);
7294 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7296 r = MsiRecordGetInteger(hrec, 1);
7297 ok(r == 7, "Expected 7, got %d\n", r);
7299 r = MsiRecordGetInteger(hrec, 2);
7300 ok(r == 8, "Expected 8, got %d\n", r);
7302 MsiRecordSetInteger(hrec, 2, 9);
7304 r = MsiViewModify(hview, MSIMODIFY_UPDATE, hrec);
7305 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7307 MsiCloseHandle(hrec);
7308 MsiViewClose(hview);
7309 MsiCloseHandle(hview);
7311 query = "SELECT * FROM `Table` WHERE `A` = 7";
7312 r = MsiDatabaseOpenView(hdb, query, &hview);
7313 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7314 r = MsiViewExecute(hview, 0);
7315 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7317 r = MsiViewFetch(hview, &hrec);
7318 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7320 r = MsiRecordGetInteger(hrec, 1);
7321 ok(r == 7, "Expected 7, got %d\n", r);
7323 r = MsiRecordGetInteger(hrec, 2);
7324 ok(r == 9, "Expected 9, got %d\n", r);
7326 query = "UPDATE `Table` SET `B` = 10 WHERE `A` = 7";
7327 r = run_query(hdb, 0, query);
7328 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7330 r = MsiViewModify(hview, MSIMODIFY_REFRESH, hrec);
7331 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7333 r = MsiRecordGetInteger(hrec, 1);
7334 ok(r == 7, "Expected 7, got %d\n", r);
7336 r = MsiRecordGetInteger(hrec, 2);
7337 ok(r == 10, "Expected 10, got %d\n", r);
7339 MsiCloseHandle(hrec);
7340 MsiViewClose(hview);
7341 MsiCloseHandle(hview);
7342 MsiCloseHandle(hdb);
7345 static BOOL create_storage(LPCSTR name)
7347 WCHAR nameW[MAX_PATH];
7354 MultiByteToWideChar(CP_ACP, 0, name, -1, nameW, MAX_PATH);
7355 hr = StgCreateDocfile(nameW, STGM_CREATE | STGM_READWRITE |
7356 STGM_DIRECT | STGM_SHARE_EXCLUSIVE, 0, &stg);
7360 hr = IStorage_CreateStream(stg, nameW, STGM_WRITE | STGM_SHARE_EXCLUSIVE,
7365 hr = IStream_Write(stm, "stgdata", 8, &count);
7370 IStream_Release(stm);
7371 IStorage_Release(stg);
7376 static void test_storages_table(void)
7378 MSIHANDLE hdb, hview, hrec;
7379 IStorage *stg, *inner;
7381 char file[MAX_PATH];
7383 WCHAR name[MAX_PATH];
7390 ok(hdb, "failed to create db\n");
7392 r = MsiDatabaseCommit(hdb);
7393 ok(r == ERROR_SUCCESS , "Failed to commit database\n");
7395 MsiCloseHandle(hdb);
7397 r = MsiOpenDatabase(msifile, MSIDBOPEN_TRANSACT, &hdb);
7398 ok(r == ERROR_SUCCESS , "Failed to open database\n");
7400 /* check the column types */
7401 hrec = get_column_info(hdb, "SELECT * FROM `_Storages`", MSICOLINFO_TYPES);
7402 ok(hrec, "failed to get column info hrecord\n");
7403 ok(check_record(hrec, 1, "s62"), "wrong hrecord type\n");
7404 ok(check_record(hrec, 2, "V0"), "wrong hrecord type\n");
7406 MsiCloseHandle(hrec);
7408 /* now try the names */
7409 hrec = get_column_info(hdb, "SELECT * FROM `_Storages`", MSICOLINFO_NAMES);
7410 ok(hrec, "failed to get column info hrecord\n");
7411 ok(check_record(hrec, 1, "Name"), "wrong hrecord type\n");
7412 ok(check_record(hrec, 2, "Data"), "wrong hrecord type\n");
7414 MsiCloseHandle(hrec);
7416 create_storage("storage.bin");
7418 hrec = MsiCreateRecord(2);
7419 MsiRecordSetString(hrec, 1, "stgname");
7421 r = MsiRecordSetStream(hrec, 2, "storage.bin");
7422 ok(r == ERROR_SUCCESS, "Failed to add stream data to the hrecord: %d\n", r);
7424 DeleteFileA("storage.bin");
7426 query = "INSERT INTO `_Storages` (`Name`, `Data`) VALUES (?, ?)";
7427 r = MsiDatabaseOpenView(hdb, query, &hview);
7428 ok(r == ERROR_SUCCESS, "Failed to open database hview: %d\n", r);
7430 r = MsiViewExecute(hview, hrec);
7431 ok(r == ERROR_SUCCESS, "Failed to execute hview: %d\n", r);
7433 MsiCloseHandle(hrec);
7434 MsiViewClose(hview);
7435 MsiCloseHandle(hview);
7437 query = "SELECT `Name`, `Data` FROM `_Storages`";
7438 r = MsiDatabaseOpenView(hdb, query, &hview);
7439 ok(r == ERROR_SUCCESS, "Failed to open database hview: %d\n", r);
7441 r = MsiViewExecute(hview, 0);
7442 ok(r == ERROR_SUCCESS, "Failed to execute hview: %d\n", r);
7444 r = MsiViewFetch(hview, &hrec);
7445 ok(r == ERROR_SUCCESS, "Failed to fetch hrecord: %d\n", r);
7448 r = MsiRecordGetString(hrec, 1, file, &size);
7449 ok(r == ERROR_SUCCESS, "Failed to get string: %d\n", r);
7450 ok(!lstrcmp(file, "stgname"), "Expected \"stgname\", got \"%s\"\n", file);
7453 lstrcpyA(buf, "apple");
7454 r = MsiRecordReadStream(hrec, 2, buf, &size);
7455 ok(r == ERROR_INVALID_DATA, "Expected ERROR_INVALID_DATA, got %d\n", r);
7456 ok(!lstrcmp(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7457 ok(size == 0, "Expected 0, got %d\n", size);
7459 MsiCloseHandle(hrec);
7461 r = MsiViewFetch(hview, &hrec);
7462 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
7464 MsiViewClose(hview);
7465 MsiCloseHandle(hview);
7467 MsiDatabaseCommit(hdb);
7468 MsiCloseHandle(hdb);
7470 MultiByteToWideChar(CP_ACP, 0, msifile, -1, name, MAX_PATH);
7471 hr = StgOpenStorage(name, NULL, STGM_DIRECT | STGM_READ |
7472 STGM_SHARE_DENY_WRITE, NULL, 0, &stg);
7473 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
7474 ok(stg != NULL, "Expected non-NULL storage\n");
7476 MultiByteToWideChar(CP_ACP, 0, "stgname", -1, name, MAX_PATH);
7477 hr = IStorage_OpenStorage(stg, name, NULL, STGM_READ | STGM_SHARE_EXCLUSIVE,
7479 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
7480 ok(inner != NULL, "Expected non-NULL storage\n");
7482 MultiByteToWideChar(CP_ACP, 0, "storage.bin", -1, name, MAX_PATH);
7483 hr = IStorage_OpenStream(inner, name, NULL, STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &stm);
7484 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
7485 ok(stm != NULL, "Expected non-NULL stream\n");
7487 hr = IStream_Read(stm, buf, MAX_PATH, &size);
7488 ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
7489 ok(size == 8, "Expected 8, got %d\n", size);
7490 ok(!lstrcmpA(buf, "stgdata"), "Expected \"stgdata\", got \"%s\"\n", buf);
7492 IStream_Release(stm);
7493 IStorage_Release(inner);
7495 IStorage_Release(stg);
7496 DeleteFileA(msifile);
7499 static void test_dbtopackage(void)
7501 MSIHANDLE hdb, hpkg;
7502 CHAR package[12], buf[MAX_PATH];
7506 /* create an empty database, transact mode */
7507 r = MsiOpenDatabase(msifile, MSIDBOPEN_CREATE, &hdb);
7508 ok(r == ERROR_SUCCESS, "Failed to create database\n");
7510 set_summary_info(hdb);
7512 r = create_directory_table(hdb);
7513 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7515 r = create_custom_action_table(hdb);
7516 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7518 r = add_custom_action_entry(hdb, "'SetProp', 51, 'MYPROP', 'grape'");
7519 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7521 sprintf(package, "#%u", hdb);
7522 r = MsiOpenPackage(package, &hpkg);
7523 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
7525 skip("Not enough rights to perform tests\n");
7528 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7530 /* property is not set yet */
7532 lstrcpyA(buf, "kiwi");
7533 r = MsiGetProperty(hpkg, "MYPROP", buf, &size);
7534 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7535 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
7536 ok(size == 0, "Expected 0, got %d\n", size);
7538 /* run the custom action to set the property */
7539 r = MsiDoAction(hpkg, "SetProp");
7540 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7542 /* property is now set */
7544 lstrcpyA(buf, "kiwi");
7545 r = MsiGetProperty(hpkg, "MYPROP", buf, &size);
7546 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7547 ok(!lstrcmpA(buf, "grape"), "Expected \"grape\", got \"%s\"\n", buf);
7548 ok(size == 5, "Expected 5, got %d\n", size);
7550 MsiCloseHandle(hpkg);
7552 /* reset the package */
7553 r = MsiOpenPackage(package, &hpkg);
7554 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7556 /* property is not set anymore */
7558 lstrcpyA(buf, "kiwi");
7559 r = MsiGetProperty(hpkg, "MYPROP", buf, &size);
7560 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7563 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
7564 ok(size == 0, "Expected 0, got %d\n", size);
7567 MsiCloseHandle(hdb);
7568 MsiCloseHandle(hpkg);
7570 /* create an empty database, direct mode */
7571 r = MsiOpenDatabase(msifile, MSIDBOPEN_CREATEDIRECT, &hdb);
7572 ok(r == ERROR_SUCCESS, "Failed to create database\n");
7574 set_summary_info(hdb);
7576 r = create_directory_table(hdb);
7577 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7579 r = create_custom_action_table(hdb);
7580 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7582 r = add_custom_action_entry(hdb, "'SetProp', 51, 'MYPROP', 'grape'");
7583 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7585 sprintf(package, "#%u", hdb);
7586 r = MsiOpenPackage(package, &hpkg);
7587 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7589 /* property is not set yet */
7591 lstrcpyA(buf, "kiwi");
7592 r = MsiGetProperty(hpkg, "MYPROP", buf, &size);
7593 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7594 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
7595 ok(size == 0, "Expected 0, got %d\n", size);
7597 /* run the custom action to set the property */
7598 r = MsiDoAction(hpkg, "SetProp");
7599 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7601 /* property is now set */
7603 lstrcpyA(buf, "kiwi");
7604 r = MsiGetProperty(hpkg, "MYPROP", buf, &size);
7605 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7606 ok(!lstrcmpA(buf, "grape"), "Expected \"grape\", got \"%s\"\n", buf);
7607 ok(size == 5, "Expected 5, got %d\n", size);
7609 MsiCloseHandle(hpkg);
7611 /* reset the package */
7612 r = MsiOpenPackage(package, &hpkg);
7613 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7615 /* property is not set anymore */
7617 lstrcpyA(buf, "kiwi");
7618 r = MsiGetProperty(hpkg, "MYPROP", buf, &size);
7619 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7622 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
7623 ok(size == 0, "Expected 0, got %d\n", size);
7626 MsiCloseHandle(hpkg);
7629 MsiCloseHandle(hdb);
7630 DeleteFileA(msifile);
7633 static void test_droptable(void)
7635 MSIHANDLE hdb, hview, hrec;
7641 r = MsiOpenDatabase(msifile, MSIDBOPEN_CREATE, &hdb);
7642 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7644 query = "CREATE TABLE `One` ( `A` INT PRIMARY KEY `A` )";
7645 r = run_query(hdb, 0, query);
7646 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7648 query = "SELECT * FROM `One`";
7649 r = do_query(hdb, query, &hrec);
7650 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
7652 query = "SELECT * FROM `_Tables` WHERE `Name` = 'One'";
7653 r = MsiDatabaseOpenViewA(hdb, query, &hview);
7654 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7655 r = MsiViewExecute(hview, 0);
7656 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7658 r = MsiViewFetch(hview, &hrec);
7659 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7662 r = MsiRecordGetStringA(hrec, 1, buf, &size);
7663 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7664 ok(!lstrcmpA(buf, "One"), "Expected \"One\", got \"%s\"\n", buf);
7666 MsiCloseHandle(hrec);
7667 MsiViewClose(hview);
7668 MsiCloseHandle(hview);
7670 query = "SELECT * FROM `_Columns` WHERE `Table` = 'One'";
7671 r = MsiDatabaseOpenViewA(hdb, query, &hview);
7672 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7673 r = MsiViewExecute(hview, 0);
7674 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7676 r = MsiViewFetch(hview, &hrec);
7677 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7680 r = MsiRecordGetStringA(hrec, 1, buf, &size);
7681 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7682 ok(!lstrcmpA(buf, "One"), "Expected \"One\", got \"%s\"\n", buf);
7684 r = MsiRecordGetInteger(hrec, 2);
7685 ok(r == 1, "Expected 1, got %d\n", r);
7688 r = MsiRecordGetStringA(hrec, 3, buf, &size);
7689 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7690 ok(!lstrcmpA(buf, "A"), "Expected \"A\", got \"%s\"\n", buf);
7692 MsiCloseHandle(hrec);
7694 r = MsiViewFetch(hview, &hrec);
7695 ok(r == ERROR_NO_MORE_ITEMS,
7696 "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
7698 MsiViewClose(hview);
7699 MsiCloseHandle(hview);
7701 query = "DROP `One`";
7702 r = run_query(hdb, 0, query);
7703 ok(r == ERROR_BAD_QUERY_SYNTAX,
7704 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
7706 query = "DROP TABLE";
7707 r = run_query(hdb, 0, query);
7708 ok(r == ERROR_BAD_QUERY_SYNTAX,
7709 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
7711 query = "DROP TABLE `One`";
7713 r = MsiDatabaseOpenViewA(hdb, query, &hview);
7714 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7715 r = MsiViewExecute(hview, 0);
7716 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7718 r = MsiViewFetch(hview, &hrec);
7719 ok(r == ERROR_FUNCTION_FAILED,
7720 "Expected ERROR_FUNCTION_FAILED, got %d\n", r);
7722 MsiViewClose(hview);
7723 MsiCloseHandle(hview);
7725 query = "SELECT * FROM `IDontExist`";
7726 r = do_query(hdb, query, &hrec);
7727 ok(r == ERROR_BAD_QUERY_SYNTAX,
7728 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
7730 query = "SELECT * FROM `One`";
7731 r = do_query(hdb, query, &hrec);
7732 ok(r == ERROR_BAD_QUERY_SYNTAX,
7733 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
7735 query = "CREATE TABLE `One` ( `A` INT PRIMARY KEY `A` )";
7736 r = run_query(hdb, 0, query);
7737 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7739 query = "DROP TABLE One";
7740 r = run_query(hdb, 0, query);
7741 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7743 query = "SELECT * FROM `One`";
7744 r = do_query(hdb, query, &hrec);
7745 ok(r == ERROR_BAD_QUERY_SYNTAX,
7746 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
7748 query = "SELECT * FROM `_Tables` WHERE `Name` = 'One'";
7749 r = do_query(hdb, query, &hrec);
7750 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
7752 query = "SELECT * FROM `_Columns` WHERE `Table` = 'One'";
7753 r = do_query(hdb, query, &hrec);
7754 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
7756 query = "CREATE TABLE `One` ( `B` INT, `C` INT PRIMARY KEY `B` )";
7757 r = run_query(hdb, 0, query);
7758 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7760 query = "SELECT * FROM `One`";
7761 r = do_query(hdb, query, &hrec);
7762 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
7764 query = "SELECT * FROM `_Tables` WHERE `Name` = 'One'";
7765 r = MsiDatabaseOpenViewA(hdb, query, &hview);
7766 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7767 r = MsiViewExecute(hview, 0);
7768 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7770 r = MsiViewFetch(hview, &hrec);
7771 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7774 r = MsiRecordGetStringA(hrec, 1, buf, &size);
7775 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7776 ok(!lstrcmpA(buf, "One"), "Expected \"One\", got \"%s\"\n", buf);
7778 MsiCloseHandle(hrec);
7779 MsiViewClose(hview);
7780 MsiCloseHandle(hview);
7782 query = "SELECT * FROM `_Columns` WHERE `Table` = 'One'";
7783 r = MsiDatabaseOpenViewA(hdb, query, &hview);
7784 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7785 r = MsiViewExecute(hview, 0);
7786 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7788 r = MsiViewFetch(hview, &hrec);
7789 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7792 r = MsiRecordGetStringA(hrec, 1, buf, &size);
7793 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7794 ok(!lstrcmpA(buf, "One"), "Expected \"One\", got \"%s\"\n", buf);
7796 r = MsiRecordGetInteger(hrec, 2);
7797 ok(r == 1, "Expected 1, got %d\n", r);
7800 r = MsiRecordGetStringA(hrec, 3, buf, &size);
7801 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7802 ok(!lstrcmpA(buf, "B"), "Expected \"B\", got \"%s\"\n", buf);
7804 MsiCloseHandle(hrec);
7806 r = MsiViewFetch(hview, &hrec);
7807 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7810 r = MsiRecordGetStringA(hrec, 1, buf, &size);
7811 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7812 ok(!lstrcmpA(buf, "One"), "Expected \"One\", got \"%s\"\n", buf);
7814 r = MsiRecordGetInteger(hrec, 2);
7815 ok(r == 2, "Expected 2, got %d\n", r);
7818 r = MsiRecordGetStringA(hrec, 3, buf, &size);
7819 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7820 ok(!lstrcmpA(buf, "C"), "Expected \"C\", got \"%s\"\n", buf);
7822 MsiCloseHandle(hrec);
7824 r = MsiViewFetch(hview, &hrec);
7825 ok(r == ERROR_NO_MORE_ITEMS,
7826 "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
7828 MsiViewClose(hview);
7829 MsiCloseHandle(hview);
7831 query = "DROP TABLE One";
7832 r = run_query(hdb, 0, query);
7833 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7835 query = "SELECT * FROM `One`";
7836 r = do_query(hdb, query, &hrec);
7837 ok(r == ERROR_BAD_QUERY_SYNTAX,
7838 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
7840 query = "SELECT * FROM `_Tables` WHERE `Name` = 'One'";
7841 r = do_query(hdb, query, &hrec);
7842 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
7844 query = "SELECT * FROM `_Columns` WHERE `Table` = 'One'";
7845 r = do_query(hdb, query, &hrec);
7846 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
7848 MsiCloseHandle(hdb);
7849 DeleteFileA(msifile);
7852 static void test_dbmerge(void)
7854 MSIHANDLE hdb, href, hview, hrec;
7860 r = MsiOpenDatabase(msifile, MSIDBOPEN_CREATE, &hdb);
7861 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7863 r = MsiOpenDatabase("refdb.msi", MSIDBOPEN_CREATE, &href);
7864 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7866 /* hDatabase is invalid */
7867 r = MsiDatabaseMergeA(0, href, "MergeErrors");
7868 ok(r == ERROR_INVALID_HANDLE,
7869 "Expected ERROR_INVALID_HANDLE, got %d\n", r);
7871 /* hDatabaseMerge is invalid */
7872 r = MsiDatabaseMergeA(hdb, 0, "MergeErrors");
7873 ok(r == ERROR_INVALID_HANDLE,
7874 "Expected ERROR_INVALID_HANDLE, got %d\n", r);
7876 /* szTableName is NULL */
7877 r = MsiDatabaseMergeA(hdb, href, NULL);
7878 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7880 /* szTableName is empty */
7881 r = MsiDatabaseMergeA(hdb, href, "");
7882 ok(r == ERROR_INVALID_TABLE, "Expected ERROR_INVALID_TABLE, got %d\n", r);
7884 /* both DBs empty, szTableName is valid */
7885 r = MsiDatabaseMergeA(hdb, href, "MergeErrors");
7886 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7888 query = "CREATE TABLE `One` ( `A` INT PRIMARY KEY `A` )";
7889 r = run_query(hdb, 0, query);
7890 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7892 query = "CREATE TABLE `One` ( `A` CHAR(72) PRIMARY KEY `A` )";
7893 r = run_query(href, 0, query);
7894 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7896 /* column types don't match */
7897 r = MsiDatabaseMergeA(hdb, href, "MergeErrors");
7898 ok(r == ERROR_DATATYPE_MISMATCH,
7899 "Expected ERROR_DATATYPE_MISMATCH, got %d\n", r);
7901 /* nothing in MergeErrors */
7902 query = "SELECT * FROM `MergeErrors`";
7903 r = do_query(hdb, query, &hrec);
7904 ok(r == ERROR_BAD_QUERY_SYNTAX,
7905 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
7907 query = "DROP TABLE `One`";
7908 r = run_query(hdb, 0, query);
7909 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7911 query = "DROP TABLE `One`";
7912 r = run_query(href, 0, query);
7913 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7915 query = "CREATE TABLE `One` ( "
7918 "`C` CHAR(64) LOCALIZABLE, "
7920 "`E` CHAR(72) NOT NULL, "
7921 "`F` CHAR(56) NOT NULL, "
7922 "`G` CHAR(64) NOT NULL LOCALIZABLE, "
7923 "`H` LONGCHAR NOT NULL "
7924 "PRIMARY KEY `A` )";
7925 r = run_query(hdb, 0, query);
7926 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7928 query = "CREATE TABLE `One` ( "
7933 "`E` CHAR(64) NOT NULL, "
7934 "`F` CHAR(64) NOT NULL, "
7935 "`G` CHAR(64) NOT NULL, "
7936 "`H` CHAR(64) NOT NULL "
7937 "PRIMARY KEY `A` )";
7938 r = run_query(href, 0, query);
7939 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7941 /* column sting types don't match exactly */
7942 r = MsiDatabaseMergeA(hdb, href, "MergeErrors");
7943 ok(r == ERROR_SUCCESS,
7944 "Expected ERROR_SUCCESS, got %d\n", r);
7946 /* nothing in MergeErrors */
7947 query = "SELECT * FROM `MergeErrors`";
7948 r = do_query(hdb, query, &hrec);
7949 ok(r == ERROR_BAD_QUERY_SYNTAX,
7950 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
7952 query = "DROP TABLE `One`";
7953 r = run_query(hdb, 0, query);
7954 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7956 query = "DROP TABLE `One`";
7957 r = run_query(href, 0, query);
7958 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7960 query = "CREATE TABLE `One` ( `A` INT, `B` INT PRIMARY KEY `A` )";
7961 r = run_query(hdb, 0, query);
7962 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7964 query = "CREATE TABLE `One` ( `A` INT, `C` INT PRIMARY KEY `A` )";
7965 r = run_query(href, 0, query);
7966 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7968 /* column names don't match */
7969 r = MsiDatabaseMergeA(hdb, href, "MergeErrors");
7970 ok(r == ERROR_DATATYPE_MISMATCH,
7971 "Expected ERROR_DATATYPE_MISMATCH, got %d\n", r);
7973 /* nothing in MergeErrors */
7974 query = "SELECT * FROM `MergeErrors`";
7975 r = do_query(hdb, query, &hrec);
7976 ok(r == ERROR_BAD_QUERY_SYNTAX,
7977 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
7979 query = "DROP TABLE `One`";
7980 r = run_query(hdb, 0, query);
7981 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7983 query = "DROP TABLE `One`";
7984 r = run_query(href, 0, query);
7985 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7987 query = "CREATE TABLE `One` ( `A` INT, `B` INT PRIMARY KEY `A` )";
7988 r = run_query(hdb, 0, query);
7989 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7991 query = "CREATE TABLE `One` ( `A` INT, `B` INT PRIMARY KEY `B` )";
7992 r = run_query(href, 0, query);
7993 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7995 /* primary keys don't match */
7996 r = MsiDatabaseMergeA(hdb, href, "MergeErrors");
7997 ok(r == ERROR_DATATYPE_MISMATCH,
7998 "Expected ERROR_DATATYPE_MISMATCH, got %d\n", r);
8000 /* nothing in MergeErrors */
8001 query = "SELECT * FROM `MergeErrors`";
8002 r = do_query(hdb, query, &hrec);
8003 ok(r == ERROR_BAD_QUERY_SYNTAX,
8004 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
8006 query = "DROP TABLE `One`";
8007 r = run_query(hdb, 0, query);
8008 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8010 query = "DROP TABLE `One`";
8011 r = run_query(href, 0, query);
8012 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8014 query = "CREATE TABLE `One` ( `A` INT, `B` INT PRIMARY KEY `A` )";
8015 r = run_query(hdb, 0, query);
8016 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8018 query = "CREATE TABLE `One` ( `A` INT, `B` INT PRIMARY KEY `A`, `B` )";
8019 r = run_query(href, 0, query);
8020 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8022 /* number of primary keys doesn't match */
8023 r = MsiDatabaseMergeA(hdb, href, "MergeErrors");
8024 ok(r == ERROR_DATATYPE_MISMATCH,
8025 "Expected ERROR_DATATYPE_MISMATCH, got %d\n", r);
8027 /* nothing in MergeErrors */
8028 query = "SELECT * FROM `MergeErrors`";
8029 r = do_query(hdb, query, &hrec);
8030 ok(r == ERROR_BAD_QUERY_SYNTAX,
8031 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
8033 query = "DROP TABLE `One`";
8034 r = run_query(hdb, 0, query);
8035 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8037 query = "DROP TABLE `One`";
8038 r = run_query(href, 0, query);
8039 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8041 query = "CREATE TABLE `One` ( `A` INT, `B` INT, `C` INT PRIMARY KEY `A` )";
8042 r = run_query(hdb, 0, query);
8043 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8045 query = "CREATE TABLE `One` ( `A` INT, `B` INT PRIMARY KEY `A` )";
8046 r = run_query(href, 0, query);
8047 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8049 query = "INSERT INTO `One` ( `A`, `B` ) VALUES ( 1, 2 )";
8050 r = run_query(href, 0, query);
8051 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8053 /* number of columns doesn't match */
8054 r = MsiDatabaseMergeA(hdb, href, "MergeErrors");
8055 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8057 query = "SELECT * FROM `One`";
8058 r = do_query(hdb, query, &hrec);
8059 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8061 r = MsiRecordGetInteger(hrec, 1);
8062 ok(r == 1, "Expected 1, got %d\n", r);
8064 r = MsiRecordGetInteger(hrec, 2);
8065 ok(r == 2, "Expected 2, got %d\n", r);
8067 r = MsiRecordGetInteger(hrec, 3);
8068 ok(r == MSI_NULL_INTEGER, "Expected MSI_NULL_INTEGER, got %d\n", r);
8070 MsiCloseHandle(hrec);
8072 /* nothing in MergeErrors */
8073 query = "SELECT * FROM `MergeErrors`";
8074 r = do_query(hdb, query, &hrec);
8075 ok(r == ERROR_BAD_QUERY_SYNTAX,
8076 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
8078 query = "DROP TABLE `One`";
8079 r = run_query(hdb, 0, query);
8080 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8082 query = "DROP TABLE `One`";
8083 r = run_query(href, 0, query);
8084 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8086 query = "CREATE TABLE `One` ( `A` INT, `B` INT PRIMARY KEY `A` )";
8087 r = run_query(hdb, 0, query);
8088 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8090 query = "CREATE TABLE `One` ( `A` INT, `B` INT, `C` INT PRIMARY KEY `A` )";
8091 r = run_query(href, 0, query);
8092 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8094 query = "INSERT INTO `One` ( `A`, `B`, `C` ) VALUES ( 1, 2, 3 )";
8095 r = run_query(href, 0, query);
8096 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8098 /* number of columns doesn't match */
8099 r = MsiDatabaseMergeA(hdb, href, "MergeErrors");
8100 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8102 query = "SELECT * FROM `One`";
8103 r = do_query(hdb, query, &hrec);
8104 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8106 r = MsiRecordGetInteger(hrec, 1);
8107 ok(r == 1, "Expected 1, got %d\n", r);
8109 r = MsiRecordGetInteger(hrec, 2);
8110 ok(r == 2, "Expected 2, got %d\n", r);
8112 r = MsiRecordGetInteger(hrec, 3);
8113 ok(r == MSI_NULL_INTEGER, "Expected MSI_NULL_INTEGER, got %d\n", r);
8115 MsiCloseHandle(hrec);
8117 /* nothing in MergeErrors */
8118 query = "SELECT * FROM `MergeErrors`";
8119 r = do_query(hdb, query, &hrec);
8120 ok(r == ERROR_BAD_QUERY_SYNTAX,
8121 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
8123 query = "DROP TABLE `One`";
8124 r = run_query(hdb, 0, query);
8125 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8127 query = "DROP TABLE `One`";
8128 r = run_query(href, 0, query);
8129 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8131 query = "CREATE TABLE `One` ( `A` INT, `B` INT PRIMARY KEY `A` )";
8132 r = run_query(hdb, 0, query);
8133 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8135 query = "INSERT INTO `One` ( `A`, `B` ) VALUES ( 1, 1 )";
8136 r = run_query(hdb, 0, query);
8137 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8139 query = "INSERT INTO `One` ( `A`, `B` ) VALUES ( 2, 2 )";
8140 r = run_query(hdb, 0, query);
8141 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8143 query = "CREATE TABLE `One` ( `A` INT, `B` INT PRIMARY KEY `A` )";
8144 r = run_query(href, 0, query);
8145 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8147 query = "INSERT INTO `One` ( `A`, `B` ) VALUES ( 1, 2 )";
8148 r = run_query(href, 0, query);
8149 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8151 query = "INSERT INTO `One` ( `A`, `B` ) VALUES ( 2, 3 )";
8152 r = run_query(href, 0, query);
8153 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8155 /* primary keys match, rows do not */
8156 r = MsiDatabaseMergeA(hdb, href, "MergeErrors");
8157 ok(r == ERROR_FUNCTION_FAILED,
8158 "Expected ERROR_FUNCTION_FAILED, got %d\n", r);
8160 /* nothing in MergeErrors */
8161 query = "SELECT * FROM `MergeErrors`";
8162 r = do_query(hdb, query, &hrec);
8163 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8166 r = MsiRecordGetStringA(hrec, 1, buf, &size);
8167 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8168 ok(!lstrcmpA(buf, "One"), "Expected \"One\", got \"%s\"\n", buf);
8170 r = MsiRecordGetInteger(hrec, 2);
8171 ok(r == 2, "Expected 2, got %d\n", r);
8173 MsiCloseHandle(hrec);
8175 r = MsiDatabaseOpenViewA(hdb, "SELECT * FROM `MergeErrors`", &hview);
8176 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8178 r = MsiViewGetColumnInfo(hview, MSICOLINFO_NAMES, &hrec);
8179 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8182 r = MsiRecordGetString(hrec, 1, buf, &size);
8183 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8184 ok(!lstrcmpA(buf, "Table"), "Expected \"Table\", got \"%s\"\n", buf);
8187 r = MsiRecordGetString(hrec, 2, buf, &size);
8188 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8189 ok(!lstrcmpA(buf, "NumRowMergeConflicts"),
8190 "Expected \"NumRowMergeConflicts\", got \"%s\"\n", buf);
8192 MsiCloseHandle(hrec);
8194 r = MsiViewGetColumnInfo(hview, MSICOLINFO_TYPES, &hrec);
8195 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8198 r = MsiRecordGetString(hrec, 1, buf, &size);
8199 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8200 ok(!lstrcmpA(buf, "s255"), "Expected \"s255\", got \"%s\"\n", buf);
8203 r = MsiRecordGetString(hrec, 2, buf, &size);
8204 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8205 ok(!lstrcmpA(buf, "i2"), "Expected \"i2\", got \"%s\"\n", buf);
8207 MsiCloseHandle(hrec);
8208 MsiViewClose(hview);
8209 MsiCloseHandle(hview);
8211 query = "DROP TABLE `MergeErrors`";
8212 r = run_query(hdb, 0, query);
8213 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8215 query = "DROP TABLE `One`";
8216 r = run_query(hdb, 0, query);
8217 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8219 query = "DROP TABLE `One`";
8220 r = run_query(href, 0, query);
8221 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8223 query = "CREATE TABLE `One` ( `A` INT, `B` CHAR(72) PRIMARY KEY `A` )";
8224 r = run_query(href, 0, query);
8225 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8227 query = "INSERT INTO `One` ( `A`, `B` ) VALUES ( 1, 'hi' )";
8228 r = run_query(href, 0, query);
8229 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8231 /* table from merged database is not in target database */
8232 r = MsiDatabaseMergeA(hdb, href, "MergeErrors");
8233 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8235 query = "SELECT * FROM `One`";
8236 r = do_query(hdb, query, &hrec);
8237 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8239 r = MsiRecordGetInteger(hrec, 1);
8240 ok(r == 1, "Expected 1, got %d\n", r);
8243 r = MsiRecordGetStringA(hrec, 2, buf, &size);
8244 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8245 ok(!lstrcmpA(buf, "hi"), "Expected \"hi\", got \"%s\"\n", buf);
8247 MsiCloseHandle(hrec);
8249 /* nothing in MergeErrors */
8250 query = "SELECT * FROM `MergeErrors`";
8251 r = do_query(hdb, query, &hrec);
8252 ok(r == ERROR_BAD_QUERY_SYNTAX,
8253 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
8255 query = "DROP TABLE `One`";
8256 r = run_query(hdb, 0, query);
8257 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8259 query = "DROP TABLE `One`";
8260 r = run_query(href, 0, query);
8261 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8263 query = "CREATE TABLE `One` ( "
8264 "`A` CHAR(72), `B` INT PRIMARY KEY `A` )";
8265 r = run_query(hdb, 0, query);
8266 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8268 query = "CREATE TABLE `One` ( "
8269 "`A` CHAR(72), `B` INT PRIMARY KEY `A` )";
8270 r = run_query(href, 0, query);
8271 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8273 query = "INSERT INTO `One` ( `A`, `B` ) VALUES ( 'hi', 1 )";
8274 r = run_query(href, 0, query);
8275 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8277 /* primary key is string */
8278 r = MsiDatabaseMergeA(hdb, href, "MergeErrors");
8279 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8281 query = "SELECT * FROM `One`";
8282 r = do_query(hdb, query, &hrec);
8283 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8286 r = MsiRecordGetStringA(hrec, 1, buf, &size);
8287 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8288 ok(!lstrcmpA(buf, "hi"), "Expected \"hi\", got \"%s\"\n", buf);
8290 r = MsiRecordGetInteger(hrec, 2);
8291 ok(r == 1, "Expected 1, got %d\n", r);
8293 MsiCloseHandle(hrec);
8295 /* nothing in MergeErrors */
8296 query = "SELECT * FROM `MergeErrors`";
8297 r = do_query(hdb, query, &hrec);
8298 ok(r == ERROR_BAD_QUERY_SYNTAX,
8299 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
8301 create_file_data("codepage.idt", "\r\n\r\n850\t_ForceCodepage\r\n", 0);
8303 GetCurrentDirectoryA(MAX_PATH, buf);
8304 r = MsiDatabaseImportA(hdb, buf, "codepage.idt");
8305 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8307 query = "DROP TABLE `One`";
8308 r = run_query(hdb, 0, query);
8309 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8311 query = "DROP TABLE `One`";
8312 r = run_query(href, 0, query);
8313 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8315 query = "CREATE TABLE `One` ( "
8316 "`A` INT, `B` CHAR(72) LOCALIZABLE PRIMARY KEY `A` )";
8317 r = run_query(hdb, 0, query);
8318 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8320 query = "CREATE TABLE `One` ( "
8321 "`A` INT, `B` CHAR(72) LOCALIZABLE PRIMARY KEY `A` )";
8322 r = run_query(href, 0, query);
8323 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8325 query = "INSERT INTO `One` ( `A`, `B` ) VALUES ( 1, 'hi' )";
8326 r = run_query(href, 0, query);
8327 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8329 /* code page does not match */
8330 r = MsiDatabaseMergeA(hdb, href, "MergeErrors");
8331 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8333 query = "SELECT * FROM `One`";
8334 r = do_query(hdb, query, &hrec);
8335 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8337 r = MsiRecordGetInteger(hrec, 1);
8338 ok(r == 1, "Expected 1, got %d\n", r);
8341 r = MsiRecordGetStringA(hrec, 2, buf, &size);
8342 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8343 ok(!lstrcmpA(buf, "hi"), "Expected \"hi\", got \"%s\"\n", buf);
8345 MsiCloseHandle(hrec);
8347 /* nothing in MergeErrors */
8348 query = "SELECT * FROM `MergeErrors`";
8349 r = do_query(hdb, query, &hrec);
8350 ok(r == ERROR_BAD_QUERY_SYNTAX,
8351 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
8353 query = "DROP TABLE `One`";
8354 r = run_query(hdb, 0, query);
8355 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8357 query = "DROP TABLE `One`";
8358 r = run_query(href, 0, query);
8359 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8361 query = "CREATE TABLE `One` ( `A` INT, `B` OBJECT PRIMARY KEY `A` )";
8362 r = run_query(hdb, 0, query);
8363 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8365 query = "CREATE TABLE `One` ( `A` INT, `B` OBJECT PRIMARY KEY `A` )";
8366 r = run_query(href, 0, query);
8367 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8369 create_file("binary.dat");
8370 hrec = MsiCreateRecord(1);
8371 MsiRecordSetStreamA(hrec, 1, "binary.dat");
8373 query = "INSERT INTO `One` ( `A`, `B` ) VALUES ( 1, ? )";
8374 r = run_query(href, hrec, query);
8375 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8377 MsiCloseHandle(hrec);
8379 /* binary data to merge */
8380 r = MsiDatabaseMergeA(hdb, href, "MergeErrors");
8381 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8383 query = "SELECT * FROM `One`";
8384 r = do_query(hdb, query, &hrec);
8385 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8387 r = MsiRecordGetInteger(hrec, 1);
8388 ok(r == 1, "Expected 1, got %d\n", r);
8391 ZeroMemory(buf, MAX_PATH);
8392 r = MsiRecordReadStream(hrec, 2, buf, &size);
8393 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8394 ok(!lstrcmpA(buf, "binary.dat\n"),
8395 "Expected \"binary.dat\\n\", got \"%s\"\n", buf);
8397 MsiCloseHandle(hrec);
8399 /* nothing in MergeErrors */
8400 query = "SELECT * FROM `MergeErrors`";
8401 r = do_query(hdb, query, &hrec);
8402 ok(r == ERROR_BAD_QUERY_SYNTAX,
8403 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
8405 query = "DROP TABLE `One`";
8406 r = run_query(hdb, 0, query);
8407 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8409 query = "DROP TABLE `One`";
8410 r = run_query(href, 0, query);
8411 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8413 query = "CREATE TABLE `One` ( `A` INT, `B` CHAR(72) PRIMARY KEY `A` )";
8414 r = run_query(hdb, 0, query);
8415 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8416 r = run_query(href, 0, query);
8417 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8419 query = "INSERT INTO `One` ( `A`, `B` ) VALUES ( 1, 'foo' )";
8420 r = run_query(href, 0, query);
8421 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8423 query = "INSERT INTO `One` ( `A`, `B` ) VALUES ( 2, 'bar' )";
8424 r = run_query(href, 0, query);
8425 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8427 r = MsiDatabaseMergeA(hdb, href, "MergeErrors");
8428 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8430 query = "SELECT * FROM `One`";
8431 r = MsiDatabaseOpenViewA(hdb, query, &hview);
8432 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8433 r = MsiViewExecute(hview, 0);
8434 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8436 r = MsiViewFetch(hview, &hrec);
8437 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8439 r = MsiRecordGetInteger(hrec, 1);
8440 ok(r == 1, "Expected 1, got %d\n", r);
8443 r = MsiRecordGetStringA(hrec, 2, buf, &size);
8444 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8445 ok(!lstrcmpA(buf, "foo"), "Expected \"foo\", got \"%s\"\n", buf);
8447 MsiCloseHandle(hrec);
8449 r = MsiViewFetch(hview, &hrec);
8450 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8452 r = MsiRecordGetInteger(hrec, 1);
8453 ok(r == 2, "Expected 2, got %d\n", r);
8456 r = MsiRecordGetStringA(hrec, 2, buf, &size);
8457 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8458 ok(!lstrcmpA(buf, "bar"), "Expected \"bar\", got \"%s\"\n", buf);
8460 MsiCloseHandle(hrec);
8462 r = MsiViewFetch(hview, &hrec);
8463 ok(r == ERROR_NO_MORE_ITEMS,
8464 "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8466 MsiViewClose(hview);
8467 MsiCloseHandle(hview);
8469 MsiCloseHandle(hdb);
8470 MsiCloseHandle(href);
8471 DeleteFileA(msifile);
8472 DeleteFileA("refdb.msi");
8473 DeleteFileA("codepage.idt");
8474 DeleteFileA("binary.dat");
8477 static void test_select_with_tablenames(void)
8479 MSIHANDLE hdb, view, rec;
8491 ok(hdb, "failed to create db\n");
8493 /* Build a pair of tables with the same column names, but unique data */
8494 query = "CREATE TABLE `T1` ( `A` SHORT, `B` SHORT PRIMARY KEY `A`)";
8495 r = run_query(hdb, 0, query);
8496 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8498 query = "INSERT INTO `T1` ( `A`, `B` ) VALUES ( 1, 2 )";
8499 r = run_query(hdb, 0, query);
8500 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8502 query = "INSERT INTO `T1` ( `A`, `B` ) VALUES ( 4, 5 )";
8503 r = run_query(hdb, 0, query);
8504 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8506 query = "CREATE TABLE `T2` ( `A` SHORT, `B` SHORT PRIMARY KEY `A`)";
8507 r = run_query(hdb, 0, query);
8508 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8510 query = "INSERT INTO `T2` ( `A`, `B` ) VALUES ( 11, 12 )";
8511 r = run_query(hdb, 0, query);
8512 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8514 query = "INSERT INTO `T2` ( `A`, `B` ) VALUES ( 14, 15 )";
8515 r = run_query(hdb, 0, query);
8516 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8519 /* Test that selection based on prefixing the column with the table
8520 * actually selects the right data */
8522 query = "SELECT T1.A, T2.B FROM T1,T2";
8523 r = MsiDatabaseOpenView(hdb, query, &view);
8524 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8525 r = MsiViewExecute(view, 0);
8526 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8528 for (i = 0; i < 4; i++)
8530 r = MsiViewFetch(view, &rec);
8531 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8533 r = MsiRecordGetInteger(rec, 1);
8534 ok(r == vals[i][0], "Expected %d, got %d\n", vals[i][0], r);
8536 r = MsiRecordGetInteger(rec, 2);
8537 ok(r == vals[i][1], "Expected %d, got %d\n", vals[i][1], r);
8539 MsiCloseHandle(rec);
8542 r = MsiViewFetch(view, &rec);
8543 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8546 MsiCloseHandle(view);
8547 MsiCloseHandle(hdb);
8548 DeleteFileA(msifile);
8551 static const UINT ordervals[6][3] =
8553 { MSI_NULL_INTEGER, 12, 13 },
8557 { 10, 11, MSI_NULL_INTEGER },
8558 { 14, MSI_NULL_INTEGER, 15 }
8561 static void test_insertorder(void)
8563 MSIHANDLE hdb, view, rec;
8569 ok(hdb, "failed to create db\n");
8571 query = "CREATE TABLE `T` ( `A` SHORT, `B` SHORT, `C` SHORT PRIMARY KEY `A`)";
8572 r = run_query(hdb, 0, query);
8573 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8575 query = "INSERT INTO `T` ( `A`, `B`, `C` ) VALUES ( 1, 2, 3 )";
8576 r = run_query(hdb, 0, query);
8577 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8579 query = "INSERT INTO `T` ( `B`, `C`, `A` ) VALUES ( 4, 5, 6 )";
8580 r = run_query(hdb, 0, query);
8581 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8583 query = "INSERT INTO `T` ( `C`, `A`, `B` ) VALUES ( 7, 8, 9 )";
8584 r = run_query(hdb, 0, query);
8585 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8587 query = "INSERT INTO `T` ( `A`, `B` ) VALUES ( 10, 11 )";
8588 r = run_query(hdb, 0, query);
8589 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8591 query = "INSERT INTO `T` ( `B`, `C` ) VALUES ( 12, 13 )";
8592 r = run_query(hdb, 0, query);
8593 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8595 /* fails because the primary key already
8596 * has an MSI_NULL_INTEGER value set above
8598 query = "INSERT INTO `T` ( `C` ) VALUES ( 14 )";
8599 r = run_query(hdb, 0, query);
8600 ok(r == ERROR_FUNCTION_FAILED,
8601 "Expected ERROR_FUNCTION_FAILED, got %d\n", r);
8603 /* replicate the error where primary key is set twice */
8604 query = "INSERT INTO `T` ( `A`, `C` ) VALUES ( 1, 14 )";
8605 r = run_query(hdb, 0, query);
8606 ok(r == ERROR_FUNCTION_FAILED,
8607 "Expected ERROR_FUNCTION_FAILED, got %d\n", r);
8609 query = "INSERT INTO `T` ( `A`, `C` ) VALUES ( 14, 15 )";
8610 r = run_query(hdb, 0, query);
8611 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8613 query = "INSERT INTO `T` VALUES ( 16 )";
8614 r = run_query(hdb, 0, query);
8615 ok(r == ERROR_BAD_QUERY_SYNTAX,
8616 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
8618 query = "INSERT INTO `T` VALUES ( 17, 18 )";
8619 r = run_query(hdb, 0, query);
8620 ok(r == ERROR_BAD_QUERY_SYNTAX,
8621 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
8623 query = "INSERT INTO `T` VALUES ( 19, 20, 21 )";
8624 r = run_query(hdb, 0, query);
8625 ok(r == ERROR_BAD_QUERY_SYNTAX,
8626 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
8628 query = "SELECT * FROM `T`";
8629 r = MsiDatabaseOpenView(hdb, query, &view);
8630 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8631 r = MsiViewExecute(view, 0);
8632 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8634 for (i = 0; i < 6; i++)
8636 r = MsiViewFetch(view, &rec);
8637 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8639 r = MsiRecordGetInteger(rec, 1);
8640 ok(r == ordervals[i][0], "Expected %d, got %d\n", ordervals[i][0], r);
8642 r = MsiRecordGetInteger(rec, 2);
8643 ok(r == ordervals[i][1], "Expected %d, got %d\n", ordervals[i][1], r);
8645 r = MsiRecordGetInteger(rec, 3);
8646 ok(r == ordervals[i][2], "Expected %d, got %d\n", ordervals[i][2], r);
8648 MsiCloseHandle(rec);
8651 r = MsiViewFetch(view, &rec);
8652 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8655 MsiCloseHandle(view);
8657 query = "DELETE FROM `T` WHERE `A` IS NULL";
8658 r = run_query(hdb, 0, query);
8659 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8661 query = "INSERT INTO `T` ( `B`, `C` ) VALUES ( 12, 13 ) TEMPORARY";
8662 r = run_query(hdb, 0, query);
8663 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8665 query = "SELECT * FROM `T`";
8666 r = MsiDatabaseOpenView(hdb, query, &view);
8667 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8668 r = MsiViewExecute(view, 0);
8669 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8671 for (i = 0; i < 6; i++)
8673 r = MsiViewFetch(view, &rec);
8674 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8676 r = MsiRecordGetInteger(rec, 1);
8677 ok(r == ordervals[i][0], "Expected %d, got %d\n", ordervals[i][0], r);
8679 r = MsiRecordGetInteger(rec, 2);
8680 ok(r == ordervals[i][1], "Expected %d, got %d\n", ordervals[i][1], r);
8682 r = MsiRecordGetInteger(rec, 3);
8683 ok(r == ordervals[i][2], "Expected %d, got %d\n", ordervals[i][2], r);
8685 MsiCloseHandle(rec);
8688 r = MsiViewFetch(view, &rec);
8689 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8692 MsiCloseHandle(view);
8693 MsiCloseHandle(hdb);
8694 DeleteFileA(msifile);
8697 static void test_columnorder(void)
8699 MSIHANDLE hdb, view, rec;
8706 ok(hdb, "failed to create db\n");
8708 /* Each column is a slot:
8709 * ---------------------
8710 * | B | C | A | E | D |
8711 * ---------------------
8713 * When a column is selected as a primary key,
8714 * the column occupying the nth primary key slot is swapped
8715 * with the current position of the primary key in question:
8717 * set primary key `D`
8718 * --------------------- ---------------------
8719 * | B | C | A | E | D | -> | D | C | A | E | B |
8720 * --------------------- ---------------------
8722 * set primary key `E`
8723 * --------------------- ---------------------
8724 * | D | C | A | E | B | -> | D | E | A | C | B |
8725 * --------------------- ---------------------
8728 query = "CREATE TABLE `T` ( `B` SHORT NOT NULL, `C` SHORT NOT NULL, "
8729 "`A` CHAR(255), `E` INT, `D` CHAR(255) NOT NULL "
8730 "PRIMARY KEY `D`, `E`)";
8731 r = run_query(hdb, 0, query);
8732 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8734 query = "SELECT * FROM `T`";
8735 r = MsiDatabaseOpenView(hdb, query, &view);
8736 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8738 r = MsiViewGetColumnInfo(view, MSICOLINFO_TYPES, &rec);
8739 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8742 lstrcpyA(buf, "kiwi");
8743 r = MsiRecordGetString(rec, 1, buf, &sz);
8744 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8745 ok(!lstrcmpA("s255", buf), "Expected \"s255\", got \"%s\"\n", buf);
8748 lstrcpyA(buf, "kiwi");
8749 r = MsiRecordGetString(rec, 2, buf, &sz);
8750 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8751 ok(!lstrcmpA("I2", buf), "Expected \"I2\", got \"%s\"\n", buf);
8754 lstrcpyA(buf, "kiwi");
8755 r = MsiRecordGetString(rec, 3, buf, &sz);
8756 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8757 ok(!lstrcmpA("S255", buf), "Expected \"S255\", got \"%s\"\n", buf);
8760 lstrcpyA(buf, "kiwi");
8761 r = MsiRecordGetString(rec, 4, buf, &sz);
8762 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8763 ok(!lstrcmpA("i2", buf), "Expected \"i2\", got \"%s\"\n", buf);
8766 lstrcpyA(buf, "kiwi");
8767 r = MsiRecordGetString(rec, 5, buf, &sz);
8768 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8769 ok(!lstrcmpA("i2", buf), "Expected \"i2\", got \"%s\"\n", buf);
8771 MsiCloseHandle(rec);
8773 r = MsiViewGetColumnInfo(view, MSICOLINFO_NAMES, &rec);
8774 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8777 lstrcpyA(buf, "kiwi");
8778 r = MsiRecordGetString(rec, 1, buf, &sz);
8779 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8780 ok(!lstrcmpA("D", buf), "Expected \"D\", got \"%s\"\n", buf);
8783 lstrcpyA(buf, "kiwi");
8784 r = MsiRecordGetString(rec, 2, buf, &sz);
8785 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8786 ok(!lstrcmpA("E", buf), "Expected \"E\", got \"%s\"\n", buf);
8789 lstrcpyA(buf, "kiwi");
8790 r = MsiRecordGetString(rec, 3, buf, &sz);
8791 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8792 ok(!lstrcmpA("A", buf), "Expected \"A\", got \"%s\"\n", buf);
8795 lstrcpyA(buf, "kiwi");
8796 r = MsiRecordGetString(rec, 4, buf, &sz);
8797 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8798 ok(!lstrcmpA("C", buf), "Expected \"C\", got \"%s\"\n", buf);
8801 lstrcpyA(buf, "kiwi");
8802 r = MsiRecordGetString(rec, 5, buf, &sz);
8803 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8804 ok(!lstrcmpA("B", buf), "Expected \"B\", got \"%s\"\n", buf);
8806 MsiCloseHandle(rec);
8808 MsiCloseHandle(view);
8810 query = "INSERT INTO `T` ( `B`, `C`, `A`, `E`, `D` ) "
8811 "VALUES ( 1, 2, 'a', 3, 'bc' )";
8812 r = run_query(hdb, 0, query);
8813 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8815 query = "SELECT * FROM `T`";
8816 r = do_query(hdb, query, &rec);
8817 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8820 lstrcpyA(buf, "kiwi");
8821 r = MsiRecordGetString(rec, 1, buf, &sz);
8822 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8823 ok(!lstrcmpA("bc", buf), "Expected \"bc\", got \"%s\"\n", buf);
8825 r = MsiRecordGetInteger(rec, 2);
8826 ok(r == 3, "Expected 3, got %d\n", r);
8829 lstrcpyA(buf, "kiwi");
8830 r = MsiRecordGetString(rec, 3, buf, &sz);
8831 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8832 ok(!lstrcmpA("a", buf), "Expected \"a\", got \"%s\"\n", buf);
8834 r = MsiRecordGetInteger(rec, 4);
8835 ok(r == 2, "Expected 2, got %d\n", r);
8837 r = MsiRecordGetInteger(rec, 5);
8838 ok(r == 1, "Expected 1, got %d\n", r);
8840 MsiCloseHandle(rec);
8842 query = "SELECT * FROM `_Columns` WHERE `Table` = 'T'";
8843 r = MsiDatabaseOpenView(hdb, query, &view);
8844 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8845 r = MsiViewExecute(view, 0);
8846 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8848 r = MsiViewFetch(view, &rec);
8849 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8852 lstrcpyA(buf, "kiwi");
8853 r = MsiRecordGetString(rec, 1, buf, &sz);
8854 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8855 ok(!lstrcmpA("T", buf), "Expected \"T\", got \"%s\"\n", buf);
8857 r = MsiRecordGetInteger(rec, 2);
8858 ok(r == 1, "Expected 1, got %d\n", r);
8861 lstrcpyA(buf, "kiwi");
8862 r = MsiRecordGetString(rec, 3, buf, &sz);
8863 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8864 ok(!lstrcmpA("D", buf), "Expected \"D\", got \"%s\"\n", buf);
8866 MsiCloseHandle(rec);
8868 r = MsiViewFetch(view, &rec);
8869 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8872 lstrcpyA(buf, "kiwi");
8873 r = MsiRecordGetString(rec, 1, buf, &sz);
8874 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8875 ok(!lstrcmpA("T", buf), "Expected \"T\", got \"%s\"\n", buf);
8877 r = MsiRecordGetInteger(rec, 2);
8878 ok(r == 2, "Expected 2, got %d\n", r);
8881 lstrcpyA(buf, "kiwi");
8882 r = MsiRecordGetString(rec, 3, buf, &sz);
8883 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8884 ok(!lstrcmpA("E", buf), "Expected \"E\", got \"%s\"\n", buf);
8886 MsiCloseHandle(rec);
8888 r = MsiViewFetch(view, &rec);
8889 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8892 lstrcpyA(buf, "kiwi");
8893 r = MsiRecordGetString(rec, 1, buf, &sz);
8894 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8895 ok(!lstrcmpA("T", buf), "Expected \"T\", got \"%s\"\n", buf);
8897 r = MsiRecordGetInteger(rec, 2);
8898 ok(r == 3, "Expected 3, got %d\n", r);
8901 lstrcpyA(buf, "kiwi");
8902 r = MsiRecordGetString(rec, 3, buf, &sz);
8903 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8904 ok(!lstrcmpA("A", buf), "Expected \"A\", got \"%s\"\n", buf);
8906 MsiCloseHandle(rec);
8908 r = MsiViewFetch(view, &rec);
8909 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8912 lstrcpyA(buf, "kiwi");
8913 r = MsiRecordGetString(rec, 1, buf, &sz);
8914 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8915 ok(!lstrcmpA("T", buf), "Expected \"T\", got \"%s\"\n", buf);
8917 r = MsiRecordGetInteger(rec, 2);
8918 ok(r == 4, "Expected 4, got %d\n", r);
8921 lstrcpyA(buf, "kiwi");
8922 r = MsiRecordGetString(rec, 3, buf, &sz);
8923 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8924 ok(!lstrcmpA("C", buf), "Expected \"C\", got \"%s\"\n", buf);
8926 MsiCloseHandle(rec);
8928 r = MsiViewFetch(view, &rec);
8929 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8932 lstrcpyA(buf, "kiwi");
8933 r = MsiRecordGetString(rec, 1, buf, &sz);
8934 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8935 ok(!lstrcmpA("T", buf), "Expected \"T\", got \"%s\"\n", buf);
8937 r = MsiRecordGetInteger(rec, 2);
8938 ok(r == 5, "Expected 5, got %d\n", r);
8941 lstrcpyA(buf, "kiwi");
8942 r = MsiRecordGetString(rec, 3, buf, &sz);
8943 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8944 ok(!lstrcmpA("B", buf), "Expected \"B\", got \"%s\"\n", buf);
8946 MsiCloseHandle(rec);
8948 r = MsiViewFetch(view, &rec);
8949 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8952 MsiCloseHandle(view);
8954 query = "CREATE TABLE `Z` ( `B` SHORT NOT NULL, `C` SHORT NOT NULL, "
8955 "`A` CHAR(255), `E` INT, `D` CHAR(255) NOT NULL "
8956 "PRIMARY KEY `C`, `A`, `D`)";
8957 r = run_query(hdb, 0, query);
8958 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8960 query = "SELECT * FROM `Z`";
8961 r = MsiDatabaseOpenView(hdb, query, &view);
8962 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8964 r = MsiViewGetColumnInfo(view, MSICOLINFO_TYPES, &rec);
8965 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8968 lstrcpyA(buf, "kiwi");
8969 r = MsiRecordGetString(rec, 1, buf, &sz);
8970 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8971 ok(!lstrcmpA("i2", buf), "Expected \"i2\", got \"%s\"\n", buf);
8974 lstrcpyA(buf, "kiwi");
8975 r = MsiRecordGetString(rec, 2, buf, &sz);
8976 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8977 ok(!lstrcmpA("S255", buf), "Expected \"S255\", got \"%s\"\n", buf);
8980 lstrcpyA(buf, "kiwi");
8981 r = MsiRecordGetString(rec, 3, buf, &sz);
8982 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8983 ok(!lstrcmpA("s255", buf), "Expected \"s255\", got \"%s\"\n", buf);
8986 lstrcpyA(buf, "kiwi");
8987 r = MsiRecordGetString(rec, 4, buf, &sz);
8988 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8989 ok(!lstrcmpA("I2", buf), "Expected \"I2\", got \"%s\"\n", buf);
8992 lstrcpyA(buf, "kiwi");
8993 r = MsiRecordGetString(rec, 5, buf, &sz);
8994 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8995 ok(!lstrcmpA("i2", buf), "Expected \"i2\", got \"%s\"\n", buf);
8997 MsiCloseHandle(rec);
8999 r = MsiViewGetColumnInfo(view, MSICOLINFO_NAMES, &rec);
9000 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9003 lstrcpyA(buf, "kiwi");
9004 r = MsiRecordGetString(rec, 1, buf, &sz);
9005 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9006 ok(!lstrcmpA("C", buf), "Expected \"C\", got \"%s\"\n", buf);
9009 lstrcpyA(buf, "kiwi");
9010 r = MsiRecordGetString(rec, 2, buf, &sz);
9011 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9012 ok(!lstrcmpA("A", buf), "Expected \"A\", got \"%s\"\n", buf);
9015 lstrcpyA(buf, "kiwi");
9016 r = MsiRecordGetString(rec, 3, buf, &sz);
9017 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9018 ok(!lstrcmpA("D", buf), "Expected \"D\", got \"%s\"\n", buf);
9021 lstrcpyA(buf, "kiwi");
9022 r = MsiRecordGetString(rec, 4, buf, &sz);
9023 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9024 ok(!lstrcmpA("E", buf), "Expected \"E\", got \"%s\"\n", buf);
9027 lstrcpyA(buf, "kiwi");
9028 r = MsiRecordGetString(rec, 5, buf, &sz);
9029 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9030 ok(!lstrcmpA("B", buf), "Expected \"B\", got \"%s\"\n", buf);
9032 MsiCloseHandle(rec);
9034 MsiCloseHandle(view);
9036 query = "INSERT INTO `Z` ( `B`, `C`, `A`, `E`, `D` ) "
9037 "VALUES ( 1, 2, 'a', 3, 'bc' )";
9038 r = run_query(hdb, 0, query);
9039 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9041 query = "SELECT * FROM `Z`";
9042 r = do_query(hdb, query, &rec);
9043 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9045 r = MsiRecordGetInteger(rec, 1);
9046 ok(r == 2, "Expected 2, got %d\n", r);
9049 lstrcpyA(buf, "kiwi");
9050 r = MsiRecordGetString(rec, 2, buf, &sz);
9051 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9052 ok(!lstrcmpA("a", buf), "Expected \"a\", got \"%s\"\n", buf);
9055 lstrcpyA(buf, "kiwi");
9056 r = MsiRecordGetString(rec, 3, buf, &sz);
9057 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9058 ok(!lstrcmpA("bc", buf), "Expected \"bc\", got \"%s\"\n", buf);
9060 r = MsiRecordGetInteger(rec, 4);
9061 ok(r == 3, "Expected 3, got %d\n", r);
9063 r = MsiRecordGetInteger(rec, 5);
9064 ok(r == 1, "Expected 1, got %d\n", r);
9066 MsiCloseHandle(rec);
9068 query = "SELECT * FROM `_Columns` WHERE `Table` = 'T'";
9069 r = MsiDatabaseOpenView(hdb, query, &view);
9070 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9071 r = MsiViewExecute(view, 0);
9072 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9074 r = MsiViewFetch(view, &rec);
9075 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9078 lstrcpyA(buf, "kiwi");
9079 r = MsiRecordGetString(rec, 1, buf, &sz);
9080 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9081 ok(!lstrcmpA("T", buf), "Expected \"T\", got \"%s\"\n", buf);
9083 r = MsiRecordGetInteger(rec, 2);
9084 ok(r == 1, "Expected 1, got %d\n", r);
9087 lstrcpyA(buf, "kiwi");
9088 r = MsiRecordGetString(rec, 3, buf, &sz);
9089 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9090 ok(!lstrcmpA("D", buf), "Expected \"D\", got \"%s\"\n", buf);
9092 MsiCloseHandle(rec);
9094 r = MsiViewFetch(view, &rec);
9095 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9098 lstrcpyA(buf, "kiwi");
9099 r = MsiRecordGetString(rec, 1, buf, &sz);
9100 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9101 ok(!lstrcmpA("T", buf), "Expected \"T\", got \"%s\"\n", buf);
9103 r = MsiRecordGetInteger(rec, 2);
9104 ok(r == 2, "Expected 2, got %d\n", r);
9107 lstrcpyA(buf, "kiwi");
9108 r = MsiRecordGetString(rec, 3, buf, &sz);
9109 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9110 ok(!lstrcmpA("E", buf), "Expected \"E\", got \"%s\"\n", buf);
9112 MsiCloseHandle(rec);
9114 r = MsiViewFetch(view, &rec);
9115 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9118 lstrcpyA(buf, "kiwi");
9119 r = MsiRecordGetString(rec, 1, buf, &sz);
9120 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9121 ok(!lstrcmpA("T", buf), "Expected \"T\", got \"%s\"\n", buf);
9123 r = MsiRecordGetInteger(rec, 2);
9124 ok(r == 3, "Expected 3, got %d\n", r);
9127 lstrcpyA(buf, "kiwi");
9128 r = MsiRecordGetString(rec, 3, buf, &sz);
9129 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9130 ok(!lstrcmpA("A", buf), "Expected \"A\", got \"%s\"\n", buf);
9132 MsiCloseHandle(rec);
9134 r = MsiViewFetch(view, &rec);
9135 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9138 lstrcpyA(buf, "kiwi");
9139 r = MsiRecordGetString(rec, 1, buf, &sz);
9140 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9141 ok(!lstrcmpA("T", buf), "Expected \"T\", got \"%s\"\n", buf);
9143 r = MsiRecordGetInteger(rec, 2);
9144 ok(r == 4, "Expected 4, got %d\n", r);
9147 lstrcpyA(buf, "kiwi");
9148 r = MsiRecordGetString(rec, 3, buf, &sz);
9149 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9150 ok(!lstrcmpA("C", buf), "Expected \"C\", got \"%s\"\n", buf);
9152 MsiCloseHandle(rec);
9154 r = MsiViewFetch(view, &rec);
9155 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9158 lstrcpyA(buf, "kiwi");
9159 r = MsiRecordGetString(rec, 1, buf, &sz);
9160 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9161 ok(!lstrcmpA("T", buf), "Expected \"T\", got \"%s\"\n", buf);
9163 r = MsiRecordGetInteger(rec, 2);
9164 ok(r == 5, "Expected 5, got %d\n", r);
9167 lstrcpyA(buf, "kiwi");
9168 r = MsiRecordGetString(rec, 3, buf, &sz);
9169 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9170 ok(!lstrcmpA("B", buf), "Expected \"B\", got \"%s\"\n", buf);
9172 MsiCloseHandle(rec);
9174 r = MsiViewFetch(view, &rec);
9175 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9178 MsiCloseHandle(view);
9180 MsiCloseHandle(hdb);
9181 DeleteFileA(msifile);
9184 static void test_createtable(void)
9186 MSIHANDLE hdb, htab = 0, hrec = 0;
9193 ok(hdb, "failed to create db\n");
9195 query = "CREATE TABLE `blah` (`foo` CHAR(72) NOT NULL PRIMARY KEY `foo`)";
9196 res = MsiDatabaseOpenView( hdb, query, &htab );
9197 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9198 if(res == ERROR_SUCCESS )
9200 res = MsiViewExecute( htab, hrec );
9201 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9203 res = MsiViewGetColumnInfo( htab, MSICOLINFO_NAMES, &hrec );
9204 todo_wine ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9206 size = sizeof(buffer);
9207 res = MsiRecordGetString(hrec, 1, buffer, &size );
9208 todo_wine ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9209 MsiCloseHandle( hrec );
9211 res = MsiViewClose( htab );
9212 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9214 res = MsiCloseHandle( htab );
9215 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9218 query = "CREATE TABLE `a` (`b` INT PRIMARY KEY `b`)";
9219 res = MsiDatabaseOpenView( hdb, query, &htab );
9220 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9221 if(res == ERROR_SUCCESS )
9223 res = MsiViewExecute( htab, 0 );
9224 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9226 res = MsiViewClose( htab );
9227 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9229 res = MsiCloseHandle( htab );
9230 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9232 query = "SELECT * FROM `a`";
9233 res = MsiDatabaseOpenView( hdb, query, &htab );
9234 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9236 res = MsiViewGetColumnInfo( htab, MSICOLINFO_NAMES, &hrec );
9237 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9240 size = sizeof(buffer);
9241 res = MsiRecordGetString(hrec, 1, buffer, &size );
9242 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9243 ok(!strcmp(buffer,"b"), "b != %s\n", buffer);
9244 MsiCloseHandle( hrec );
9246 res = MsiViewClose( htab );
9247 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9249 res = MsiCloseHandle( htab );
9250 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9252 res = MsiDatabaseCommit(hdb);
9253 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9255 res = MsiCloseHandle(hdb);
9256 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9258 res = MsiOpenDatabase(msifile, MSIDBOPEN_TRANSACT, &hdb );
9259 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9261 query = "SELECT * FROM `a`";
9262 res = MsiDatabaseOpenView( hdb, query, &htab );
9263 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9265 res = MsiViewGetColumnInfo( htab, MSICOLINFO_NAMES, &hrec );
9266 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9269 size = sizeof(buffer);
9270 res = MsiRecordGetString(hrec, 1, buffer, &size );
9271 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9272 todo_wine ok(!strcmp(buffer,"b"), "b != %s\n", buffer);
9274 res = MsiCloseHandle( hrec );
9275 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9277 res = MsiViewClose( htab );
9278 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9280 res = MsiCloseHandle( htab );
9281 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9284 res = MsiDatabaseCommit(hdb);
9285 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9287 res = MsiCloseHandle(hdb);
9288 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9290 DeleteFileA(msifile);
9293 static void test_embedded_nulls(void)
9295 static const char control_table[] =
9299 "LicenseAgreementDlg\ttext\x11\x19text\0text";
9301 MSIHANDLE hdb, hrec;
9304 r = MsiOpenDatabaseA( msifile, MSIDBOPEN_CREATE, &hdb );
9305 ok( r == ERROR_SUCCESS, "failed to open database %u\n", r );
9307 GetCurrentDirectoryA( MAX_PATH, CURR_DIR );
9308 write_file( "temp_file", control_table, sizeof(control_table) );
9309 r = MsiDatabaseImportA( hdb, CURR_DIR, "temp_file" );
9310 ok( r == ERROR_SUCCESS, "failed to import table %u\n", r );
9311 DeleteFileA( "temp_file" );
9313 r = do_query( hdb, "SELECT `Text` FROM `Control` WHERE `Dialog` = 'LicenseAgreementDlg'", &hrec );
9314 ok( r == ERROR_SUCCESS, "query failed %u\n", r );
9317 sz = sizeof(buffer);
9318 r = MsiRecordGetStringA( hrec, 1, buffer, &sz );
9319 ok( r == ERROR_SUCCESS, "failed to get string %u\n", r );
9320 ok( !memcmp( "text\r\ntext\ntext", buffer, sizeof("text\r\ntext\ntext") - 1 ), "wrong buffer contents \"%s\"\n", buffer );
9322 MsiCloseHandle( hrec );
9323 MsiCloseHandle( hdb );
9324 DeleteFileA( msifile );
9331 test_msidecomposedesc();
9332 test_msibadqueries();
9334 test_viewgetcolumninfo();
9340 test_where_not_in_selected();
9343 test_binary_import();
9345 test_handle_limit();
9346 test_try_transform();
9348 test_temporary_table();
9352 test_special_tables();
9353 test_tables_order();
9355 test_select_markers();
9356 test_viewmodify_update();
9357 test_viewmodify_assign();
9359 test_viewmodify_delete();
9360 test_defaultdatabase();
9362 test_viewmodify_delete_temporary();
9365 test_carriagereturn();
9367 test_forcecodepage();
9368 test_viewmodify_refresh();
9369 test_where_viewmodify();
9370 test_storages_table();
9374 test_select_with_tablenames();
9377 test_suminfo_import();
9380 test_embedded_nulls();