msi: Create a function to copy record fields, use it to order INSERT fields correctly.

This commit is contained in:
Mike McCormack 2006-08-31 17:05:45 +09:00 committed by Alexandre Julliard
parent 6b4ada6f43
commit 71d8f4ebf6
4 changed files with 73 additions and 9 deletions

View File

@ -66,7 +66,6 @@ static MSIRECORD *INSERT_merge_record( UINT fields, column_info *vl, MSIRECORD *
{ {
MSIRECORD *merged; MSIRECORD *merged;
DWORD wildcard_count = 1, i; DWORD wildcard_count = 1, i;
const WCHAR *str;
merged = MSI_CreateRecord( fields ); merged = MSI_CreateRecord( fields );
for( i=1; i <= fields; i++ ) for( i=1; i <= fields; i++ )
@ -88,10 +87,7 @@ static MSIRECORD *INSERT_merge_record( UINT fields, column_info *vl, MSIRECORD *
case EXPR_WILDCARD: case EXPR_WILDCARD:
if( !rec ) if( !rec )
goto err; goto err;
if( MSI_RecordIsNull( rec, wildcard_count ) ) MSI_RecordCopyField( rec, wildcard_count, merged, i );
goto err;
str = MSI_RecordGetString( rec, wildcard_count );
MSI_RecordSetStringW( merged, i, str );
wildcard_count++; wildcard_count++;
break; break;
default: default:

View File

@ -371,6 +371,7 @@ extern UINT MSI_RecordSetStreamW( MSIRECORD *, unsigned int, LPCWSTR );
extern UINT MSI_RecordSetStreamA( MSIRECORD *, unsigned int, LPCSTR ); extern UINT MSI_RecordSetStreamA( MSIRECORD *, unsigned int, LPCSTR );
extern UINT MSI_RecordDataSize( MSIRECORD *, unsigned int ); extern UINT MSI_RecordDataSize( MSIRECORD *, unsigned int );
extern UINT MSI_RecordStreamToFile( MSIRECORD *, unsigned int, LPCWSTR ); extern UINT MSI_RecordStreamToFile( MSIRECORD *, unsigned int, LPCWSTR );
extern UINT MSI_RecordCopyField( MSIRECORD *, unsigned int, MSIRECORD *, unsigned int );
/* stream internals */ /* stream internals */
extern UINT get_raw_stream( MSIHANDLE hdb, LPCWSTR stname, IStream **stm ); extern UINT get_raw_stream( MSIHANDLE hdb, LPCWSTR stname, IStream **stm );

View File

@ -43,7 +43,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(msidb);
#define MSIFIELD_NULL 0 #define MSIFIELD_NULL 0
#define MSIFIELD_INT 1 #define MSIFIELD_INT 1
#define MSIFIELD_STR 2
#define MSIFIELD_WSTR 3 #define MSIFIELD_WSTR 3
#define MSIFIELD_STREAM 4 #define MSIFIELD_STREAM 4
@ -154,6 +153,53 @@ static BOOL string2intW( LPCWSTR str, int *out )
return TRUE; return TRUE;
} }
UINT MSI_RecordCopyField( MSIRECORD *in_rec, unsigned int in_n,
MSIRECORD *out_rec, unsigned int out_n )
{
UINT r = ERROR_SUCCESS;
msiobj_lock( &in_rec->hdr );
if ( in_n > in_rec->count || out_n > out_rec->count )
r = ERROR_FUNCTION_FAILED;
else if ( in_rec != out_rec || in_n != out_n )
{
LPWSTR str;
MSIFIELD *in, *out;
in = &in_rec->fields[in_n];
out = &out_rec->fields[out_n];
switch ( in->type )
{
case MSIFIELD_NULL:
break;
case MSIFIELD_INT:
out->u.iVal = in->u.iVal;
break;
case MSIFIELD_WSTR:
str = strdupW( in->u.szwVal );
if ( !str )
r = ERROR_OUTOFMEMORY;
else
out->u.szwVal = str;
break;
case MSIFIELD_STREAM:
IStream_AddRef( in->u.stream );
out->u.stream = in->u.stream;
break;
default:
ERR("invalid field type %d\n", in->type);
}
if (r == ERROR_SUCCESS)
out->type = in->type;
}
msiobj_unlock( &in_rec->hdr );
return r;
}
int MSI_RecordGetInteger( MSIRECORD *rec, unsigned int iField) int MSI_RecordGetInteger( MSIRECORD *rec, unsigned int iField)
{ {
int ret = 0; int ret = 0;

View File

@ -102,13 +102,34 @@ static UINT SELECT_set_int( struct tagMSIVIEW *view, UINT row, UINT col, UINT va
static UINT SELECT_insert_row( struct tagMSIVIEW *view, MSIRECORD *record ) static UINT SELECT_insert_row( struct tagMSIVIEW *view, MSIRECORD *record )
{ {
MSISELECTVIEW *sv = (MSISELECTVIEW*)view; MSISELECTVIEW *sv = (MSISELECTVIEW*)view;
UINT i, table_cols, r;
MSIRECORD *outrec;
TRACE("%p %p\n", sv, record ); TRACE("%p %p\n", sv, record );
if ( !sv->table ) if ( !sv->table )
return ERROR_FUNCTION_FAILED; return ERROR_FUNCTION_FAILED;
return sv->table->ops->insert_row( sv->table, record ); /* rearrange the record to suit the table */
r = sv->table->ops->get_dimensions( sv->table, NULL, &table_cols );
if (r != ERROR_SUCCESS)
return r;
outrec = MSI_CreateRecord( table_cols + 1 );
for (i=0; i<sv->num_cols; i++)
{
r = MSI_RecordCopyField( record, i+1, outrec, sv->cols[i] );
if (r != ERROR_SUCCESS)
goto fail;
}
r = sv->table->ops->insert_row( sv->table, outrec );
fail:
msiobj_release( &outrec->hdr );
return r;
} }
static UINT SELECT_execute( struct tagMSIVIEW *view, MSIRECORD *record ) static UINT SELECT_execute( struct tagMSIVIEW *view, MSIRECORD *record )