Fix and test inserting records.
This commit is contained in:
parent
81b13c4bb5
commit
5007de8b05
|
@ -44,7 +44,7 @@ typedef struct tagMSIINSERTVIEW
|
|||
MSIDATABASE *db;
|
||||
BOOL bIsTemp;
|
||||
MSIVIEW *sv;
|
||||
value_list *vals; /* looks like these may be ignored... */
|
||||
value_list *vals;
|
||||
} MSIINSERTVIEW;
|
||||
|
||||
static UINT INSERT_fetch_int( struct tagMSIVIEW *view, UINT row, UINT col, UINT *val )
|
||||
|
@ -56,11 +56,62 @@ static UINT INSERT_fetch_int( struct tagMSIVIEW *view, UINT row, UINT col, UINT
|
|||
return ERROR_FUNCTION_FAILED;
|
||||
}
|
||||
|
||||
/*
|
||||
* INSERT_merge_record
|
||||
*
|
||||
* Merge a value_list and a record to create a second record.
|
||||
* Replace wildcard entries in the valuelist with values from the record
|
||||
*/
|
||||
static MSIRECORD *INSERT_merge_record( UINT fields, value_list *vl, MSIRECORD *rec )
|
||||
{
|
||||
MSIRECORD *merged;
|
||||
DWORD wildcard_count = 1, i;
|
||||
const WCHAR *str;
|
||||
|
||||
merged = MSI_CreateRecord( fields );
|
||||
for( i=1; i <= fields; i++ )
|
||||
{
|
||||
if( !vl )
|
||||
{
|
||||
TRACE("Not enough elements in the list to insert\n");
|
||||
goto err;
|
||||
}
|
||||
switch( vl->val->type )
|
||||
{
|
||||
case EXPR_SVAL:
|
||||
TRACE("field %ld -> %s\n", i, debugstr_w(vl->val->u.sval));
|
||||
MSI_RecordSetStringW( merged, i, vl->val->u.sval );
|
||||
break;
|
||||
case EXPR_IVAL:
|
||||
MSI_RecordSetInteger( merged, i, vl->val->u.ival );
|
||||
break;
|
||||
case EXPR_WILDCARD:
|
||||
if( !rec )
|
||||
goto err;
|
||||
if( MSI_RecordIsNull( rec, wildcard_count ) )
|
||||
goto err;
|
||||
str = MSI_RecordGetString( rec, wildcard_count );
|
||||
MSI_RecordSetStringW( merged, i, str );
|
||||
wildcard_count++;
|
||||
break;
|
||||
default:
|
||||
ERR("Unknown expression type %d\n", vl->val->type);
|
||||
}
|
||||
vl = vl->next;
|
||||
}
|
||||
|
||||
return merged;
|
||||
err:
|
||||
msiobj_release( &merged->hdr );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static UINT INSERT_execute( struct tagMSIVIEW *view, MSIRECORD *record )
|
||||
{
|
||||
MSIINSERTVIEW *iv = (MSIINSERTVIEW*)view;
|
||||
UINT n, type, val, r, row, col_count = 0;
|
||||
MSIVIEW *sv;
|
||||
MSIRECORD *values = NULL;
|
||||
|
||||
TRACE("%p %p\n", iv, record );
|
||||
|
||||
|
@ -77,12 +128,13 @@ static UINT INSERT_execute( struct tagMSIVIEW *view, MSIRECORD *record )
|
|||
if( r )
|
||||
goto err;
|
||||
|
||||
n = MSI_RecordGetFieldCount( record );
|
||||
if( n != col_count )
|
||||
{
|
||||
ERR("Number of fields do not match\n");
|
||||
/*
|
||||
* Merge the wildcard values into the list of values provided
|
||||
* in the query, and create a record containing both.
|
||||
*/
|
||||
values = INSERT_merge_record( col_count, iv->vals, record );
|
||||
if( !values )
|
||||
goto err;
|
||||
}
|
||||
|
||||
row = -1;
|
||||
r = sv->ops->insert_row( sv, &row );
|
||||
|
@ -98,12 +150,12 @@ static UINT INSERT_execute( struct tagMSIVIEW *view, MSIRECORD *record )
|
|||
|
||||
if( type & MSITYPE_STRING )
|
||||
{
|
||||
const WCHAR *str = MSI_RecordGetString( record, n );
|
||||
const WCHAR *str = MSI_RecordGetString( values, n );
|
||||
val = msi_addstringW( iv->db->strings, 0, str, -1, 1 );
|
||||
}
|
||||
else
|
||||
{
|
||||
val = MSI_RecordGetInteger( record, n );
|
||||
val = MSI_RecordGetInteger( values, n );
|
||||
val |= 0x8000;
|
||||
}
|
||||
r = sv->ops->set_int( sv, row, n, val );
|
||||
|
@ -112,6 +164,9 @@ static UINT INSERT_execute( struct tagMSIVIEW *view, MSIRECORD *record )
|
|||
}
|
||||
|
||||
err:
|
||||
if( values )
|
||||
msiobj_release( &values->hdr );
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
|
@ -499,18 +499,17 @@ constlist:
|
|||
}
|
||||
$$ = vals;
|
||||
}
|
||||
| constlist TK_COMMA const_val
|
||||
| const_val TK_COMMA constlist
|
||||
{
|
||||
value_list *vals;
|
||||
|
||||
vals = HeapAlloc( GetProcessHeap(), 0, sizeof *vals );
|
||||
if( vals )
|
||||
{
|
||||
vals->val = $3;
|
||||
vals->next = NULL;
|
||||
vals->val = $1;
|
||||
vals->next = $3;
|
||||
}
|
||||
$1->next = vals;
|
||||
$$ = $1;
|
||||
$$ = vals;
|
||||
}
|
||||
;
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
|
||||
#include "wine/test.h"
|
||||
|
||||
START_TEST(db)
|
||||
static void test_msidatabase(void)
|
||||
{
|
||||
MSIHANDLE hdb = 0;
|
||||
CHAR szName[] = "C:\\mytest.msi";
|
||||
|
@ -42,3 +42,86 @@ START_TEST(db)
|
|||
res = MsiCloseHandle( hdb );
|
||||
ok( res == ERROR_SUCCESS , "Failed to close database" );
|
||||
}
|
||||
|
||||
void test_msiinsert(void)
|
||||
{
|
||||
const char *msifile = "winetest.msi";
|
||||
MSIHANDLE hdb = 0, hview = 0, hrec = 0;
|
||||
UINT r;
|
||||
char *query, buf[80];
|
||||
DWORD sz;
|
||||
|
||||
DeleteFile(msifile);
|
||||
|
||||
/* just MsiOpenDatabase should not create a file */
|
||||
r = MsiOpenDatabase(msifile, MSIDBOPEN_CREATE, &hdb);
|
||||
ok(r == ERROR_SUCCESS, "MsiOpenDatabase failed\n");
|
||||
|
||||
/* create a table */
|
||||
query = "CREATE TABLE `phone` ( "
|
||||
"`id` INT, `name` CHAR(32), `number` CHAR(32) "
|
||||
"PRIMARY KEY `id`)";
|
||||
r = MsiDatabaseOpenView(hdb, query, &hview);
|
||||
ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
|
||||
r = MsiViewExecute(hview, 0);
|
||||
ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n");
|
||||
r = MsiViewClose(hview);
|
||||
ok(r == ERROR_SUCCESS, "MsiViewClose failed\n");
|
||||
r = MsiCloseHandle(hview);
|
||||
ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
|
||||
|
||||
/* insert a value into it */
|
||||
query = "INSERT INTO `phone` ( `id`, `name`, `number` )"
|
||||
"VALUES('1', 'Abe', '8675309')";
|
||||
r = MsiDatabaseOpenView(hdb, query, &hview);
|
||||
ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
|
||||
r = MsiViewExecute(hview, 0);
|
||||
ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n");
|
||||
r = MsiViewClose(hview);
|
||||
ok(r == ERROR_SUCCESS, "MsiViewClose failed\n");
|
||||
r = MsiCloseHandle(hview);
|
||||
ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
|
||||
|
||||
query = "SELECT * FROM `phone`";
|
||||
r = MsiDatabaseOpenView(hdb, query, &hview);
|
||||
ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
|
||||
r = MsiViewExecute(hview, 0);
|
||||
ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n");
|
||||
r = MsiViewFetch(hview, &hrec);
|
||||
ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n");
|
||||
|
||||
/* check the record contains what we put in it */
|
||||
r = MsiRecordGetFieldCount(hrec);
|
||||
ok(r == 3, "record count wrong\n");
|
||||
|
||||
r = MsiRecordGetInteger(hrec, 1);
|
||||
ok(r == 1, "field 1 contents wrong\n");
|
||||
sz = sizeof buf;
|
||||
r = MsiRecordGetString(hrec, 2, buf, &sz);
|
||||
ok(r == ERROR_SUCCESS, "field 2 content fetch failed\n");
|
||||
ok(!strcmp(buf,"Abe"), "field 2 content incorrect\n");
|
||||
sz = sizeof buf;
|
||||
r = MsiRecordGetString(hrec, 3, buf, &sz);
|
||||
ok(r == ERROR_SUCCESS, "field 3 content fetch failed\n");
|
||||
ok(!strcmp(buf,"8675309"), "field 3 content incorrect\n");
|
||||
|
||||
r = MsiViewClose(hview);
|
||||
ok(r == ERROR_SUCCESS, "MsiViewClose failed\n");
|
||||
r = MsiCloseHandle(hview);
|
||||
ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
|
||||
|
||||
r = MsiDatabaseCommit(hdb);
|
||||
ok(r == ERROR_SUCCESS, "MsiDatabaseCommit failed\n");
|
||||
|
||||
r = MsiCloseHandle(hdb);
|
||||
ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
|
||||
|
||||
r = DeleteFile(msifile);
|
||||
ok(r == TRUE, "file didn't exist after commit\n");
|
||||
}
|
||||
|
||||
START_TEST(db)
|
||||
{
|
||||
test_msidatabase();
|
||||
test_msiinsert();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue