Implement MsiModifyView (MSIMODIFY_INSERT_TEMPORARY).

This commit is contained in:
Mike McCormack 2005-08-24 11:10:23 +00:00 committed by Alexandre Julliard
parent 1bac61f8e5
commit e8d1a167df
6 changed files with 188 additions and 76 deletions

View file

@ -60,10 +60,11 @@ static UINT CREATE_execute( struct tagMSIVIEW *view, MSIRECORD *record )
{
MSICREATEVIEW *cv = (MSICREATEVIEW*)view;
column_info *col;
UINT r, nField, row, table_val, column_val;
UINT r, nField;
static const WCHAR szTables[] = { '_','T','a','b','l','e','s',0 };
static const WCHAR szColumns[] = { '_','C','o','l','u','m','n','s',0 };
MSIVIEW *tv = NULL;
MSIRECORD *rec;
TRACE("%p Table %s (%s)\n", cv, debugstr_w(cv->name),
cv->bIsTemp?"temporary":"permanent");
@ -72,12 +73,6 @@ static UINT CREATE_execute( struct tagMSIVIEW *view, MSIRECORD *record )
if( TABLE_Exists(cv->db, cv->name ) )
return ERROR_BAD_QUERY_SYNTAX;
/* add the name to the _Tables table */
table_val = msi_addstringW( cv->db->strings, 0, cv->name, -1, 1 );
TRACE("New string %s -> %d\n", debugstr_w( cv->name ), table_val );
if( table_val < 0 )
return ERROR_FUNCTION_FAILED;
r = TABLE_CreateView( cv->db, szTables, &tv );
TRACE("CreateView returned %x\n", r);
if( r )
@ -86,20 +81,26 @@ static UINT CREATE_execute( struct tagMSIVIEW *view, MSIRECORD *record )
r = tv->ops->execute( tv, 0 );
TRACE("tv execute returned %x\n", r);
if( r )
return r;
goto err;
row = -1;
r = tv->ops->insert_row( tv, &row );
rec = MSI_CreateRecord( 1 );
if( !rec )
goto err;
r = MSI_RecordSetStringW( rec, 1, cv->name );
if( r )
goto err;
r = tv->ops->insert_row( tv, rec );
TRACE("insert_row returned %x\n", r);
if( r )
goto err;
r = tv->ops->set_int( tv, row, 1, table_val );
if( r )
goto err;
tv->ops->delete( tv );
tv = NULL;
msiobj_release( &rec->hdr );
/* add each column to the _Columns table */
r = TABLE_CreateView( cv->db, szColumns, &tv );
if( r )
@ -108,7 +109,15 @@ static UINT CREATE_execute( struct tagMSIVIEW *view, MSIRECORD *record )
r = tv->ops->execute( tv, 0 );
TRACE("tv execute returned %x\n", r);
if( r )
return r;
goto err;
rec = MSI_CreateRecord( 4 );
if( !rec )
goto err;
r = MSI_RecordSetStringW( rec, 1, cv->name );
if( r )
goto err;
/*
* need to set the table, column number, col name and type
@ -117,36 +126,21 @@ static UINT CREATE_execute( struct tagMSIVIEW *view, MSIRECORD *record )
nField = 1;
for( col = cv->col_info; col; col = col->next )
{
row = -1;
r = tv->ops->insert_row( tv, &row );
r = MSI_RecordSetInteger( rec, 2, nField );
if( r )
goto err;
column_val = msi_addstringW( cv->db->strings, 0, col->column, -1, 1 );
TRACE("New string %s -> %d\n", debugstr_w( col->column ), column_val );
if( column_val < 0 )
break;
/* add the string again here so we increase the reference count */
table_val = msi_addstringW( cv->db->strings, 0, cv->name, -1, 1 );
if( table_val < 0 )
break;
r = tv->ops->set_int( tv, row, 1, table_val );
r = MSI_RecordSetStringW( rec, 3, col->column );
if( r )
break;
goto err;
r = tv->ops->set_int( tv, row, 2, 0x8000|nField );
r = MSI_RecordSetInteger( rec, 4, col->type );
if( r )
break;
goto err;
r = tv->ops->set_int( tv, row, 3, column_val );
r = tv->ops->insert_row( tv, rec );
if( r )
break;
r = tv->ops->set_int( tv, row, 4, 0x8000|col->type );
if( r )
break;
goto err;
nField++;
}

View file

@ -82,11 +82,11 @@ static UINT DELETE_set_int( struct tagMSIVIEW *view, UINT row, UINT col, UINT va
return ERROR_FUNCTION_FAILED;
}
static UINT DELETE_insert_row( struct tagMSIVIEW *view, UINT *num )
static UINT DELETE_insert_row( struct tagMSIVIEW *view, MSIRECORD *record )
{
MSIDELETEVIEW *dv = (MSIDELETEVIEW*)view;
TRACE("%p %p\n", dv, num );
TRACE("%p %p\n", dv, record );
return ERROR_FUNCTION_FAILED;
}

View file

@ -109,7 +109,7 @@ err:
static UINT INSERT_execute( struct tagMSIVIEW *view, MSIRECORD *record )
{
MSIINSERTVIEW *iv = (MSIINSERTVIEW*)view;
UINT n, type, val, r, row, col_count = 0;
UINT r, col_count = 0;
MSIVIEW *sv;
MSIRECORD *values = NULL;
@ -136,38 +136,13 @@ static UINT INSERT_execute( struct tagMSIVIEW *view, MSIRECORD *record )
if( !values )
goto err;
row = -1;
r = sv->ops->insert_row( sv, &row );
TRACE("insert_row returned %x\n", r);
if( r )
goto err;
for( n = 1; n <= col_count; n++ )
{
r = sv->ops->get_column_info( sv, n, NULL, &type );
if( r )
break;
if( type & MSITYPE_STRING )
{
const WCHAR *str = MSI_RecordGetString( values, n );
val = msi_addstringW( iv->db->strings, 0, str, -1, 1 );
}
else
{
val = MSI_RecordGetInteger( values, n );
val |= 0x8000;
}
r = sv->ops->set_int( sv, row, n, val );
if( r )
break;
}
r = sv->ops->insert_row( sv, values );
err:
if( values )
msiobj_release( &values->hdr );
return ERROR_SUCCESS;
return r;
}

View file

@ -129,10 +129,9 @@ typedef struct tagMSIVIEWOPS
UINT (*set_int)( struct tagMSIVIEW *, UINT row, UINT col, UINT val );
/*
* Inserts a new, blank row into the database
* *row receives the number of the new row
* Inserts a new row into the database from the records contents
*/
UINT (*insert_row)( struct tagMSIVIEW *, UINT *row );
UINT (*insert_row)( struct tagMSIVIEW *, MSIRECORD * );
/*
* execute - loads the underlying data into memory so it can be read

View file

@ -99,16 +99,16 @@ static UINT SELECT_set_int( struct tagMSIVIEW *view, UINT row, UINT col, UINT va
return sv->table->ops->set_int( sv->table, row, col, val );
}
static UINT SELECT_insert_row( struct tagMSIVIEW *view, UINT *num )
static UINT SELECT_insert_row( struct tagMSIVIEW *view, MSIRECORD *record )
{
MSISELECTVIEW *sv = (MSISELECTVIEW*)view;
TRACE("%p %p\n", sv, num );
TRACE("%p %p\n", sv, record );
if( !sv->table )
return ERROR_FUNCTION_FAILED;
return sv->table->ops->insert_row( sv->table, num );
return sv->table->ops->insert_row( sv->table, record );
}
static UINT SELECT_execute( struct tagMSIVIEW *view, MSIRECORD *record )

View file

@ -1192,7 +1192,7 @@ static UINT TABLE_set_int( struct tagMSIVIEW *view, UINT row, UINT col, UINT val
return ERROR_SUCCESS;
}
static UINT TABLE_insert_row( struct tagMSIVIEW *view, UINT *num )
static UINT table_create_new_row( struct tagMSIVIEW *view, UINT *num )
{
MSITABLEVIEW *tv = (MSITABLEVIEW*)view;
USHORT **p, *row;
@ -1242,7 +1242,7 @@ static UINT TABLE_execute( struct tagMSIVIEW *view, MSIRECORD *record )
r = get_table( tv->db, tv->name, &tv->table );
if( r != ERROR_SUCCESS )
return r;
return ERROR_SUCCESS;
}
@ -1301,11 +1301,155 @@ static UINT TABLE_get_column_info( struct tagMSIVIEW *view,
return ERROR_SUCCESS;
}
static UINT table_find_in_column( MSITABLEVIEW *tv, UINT col, UINT val, UINT *row )
{
UINT i, r, x;
for( i=0; i<tv->table->row_count; i++ )
{
r = TABLE_fetch_int( (struct tagMSIVIEW*) tv, i, col, &x );
if ( r != ERROR_SUCCESS )
{
ERR("TABLE_fetch_int shouldn't fail here\n");
break;
}
if ( x == val )
{
*row = i;
return ERROR_SUCCESS;
}
}
return ERROR_FUNCTION_FAILED;
}
static UINT table_validate_new( MSITABLEVIEW *tv, MSIRECORD *rec )
{
LPCWSTR str;
UINT i, val, r, row;
/* FIXME: set the MsiViewGetError value */
for( i = 0; i<tv->num_cols; i++ )
{
/* check for duplicate keys */
if( !( tv->columns[i].type & MSITYPE_KEY ) )
continue;
TRACE("column %d (%s.%s)is a key\n", i,
debugstr_w(tv->columns[i].tablename),
debugstr_w(tv->columns[i].colname) );
val = 0;
if( tv->columns[i].type & MSITYPE_STRING )
{
/* keys can't be null */
str = MSI_RecordGetString( rec, i+1 );
if( !str )
return ERROR_INVALID_DATA;
/* if the string doesn't exist in the string table yet, it's OK */
r = msi_string2idW( tv->db->strings, str, &val );
if( ERROR_SUCCESS != r )
continue;
}
else
{
val = MSI_RecordGetInteger( rec, i+1 );
val ^= 0x8000;
}
/* if we find the same value in the table, it's a duplicate */
row = 0;
r = table_find_in_column( tv, i+1, val, &row );
if( ERROR_SUCCESS == r )
{
TRACE("found in row %d\n", row );
return ERROR_INVALID_DATA;
}
}
return ERROR_SUCCESS;
}
static UINT TABLE_insert_row( struct tagMSIVIEW *view, MSIRECORD *rec )
{
MSITABLEVIEW *tv = (MSITABLEVIEW*)view;
UINT n, type, val, r, row, col_count = 0;
r = TABLE_get_dimensions( view, NULL, &col_count );
if( r )
return r;
row = -1;
r = table_create_new_row( view, &row );
TRACE("insert_row returned %08x\n", r);
if( r )
return r;
for( n = 1; n <= col_count; n++ )
{
r = TABLE_get_column_info( view, n, NULL, &type );
if( r )
break;
if( type & MSITYPE_STRING )
{
const WCHAR *str = MSI_RecordGetString( rec, n );
val = msi_addstringW( tv->db->strings, 0, str, -1, 1 );
}
else
{
val = MSI_RecordGetInteger( rec, n );
val ^= 0x8000;
}
r = TABLE_set_int( view, row, n, val );
if( r )
break;
}
return r;
}
static UINT TABLE_modify( struct tagMSIVIEW *view, MSIMODIFY eModifyMode,
MSIRECORD *rec)
{
FIXME("%p %d %p\n", view, eModifyMode, rec );
return ERROR_CALL_NOT_IMPLEMENTED;
MSITABLEVIEW *tv = (MSITABLEVIEW*)view;
UINT r;
TRACE("%p %d %p\n", view, eModifyMode, rec );
switch (eModifyMode)
{
case MSIMODIFY_VALIDATE_NEW:
r = table_validate_new( tv, rec );
break;
case MSIMODIFY_INSERT_TEMPORARY:
r = table_validate_new( tv, rec );
if (r != ERROR_SUCCESS)
break;
r = TABLE_insert_row( view, rec );
break;
case MSIMODIFY_REFRESH:
case MSIMODIFY_INSERT:
case MSIMODIFY_UPDATE:
case MSIMODIFY_ASSIGN:
case MSIMODIFY_REPLACE:
case MSIMODIFY_MERGE:
case MSIMODIFY_DELETE:
case MSIMODIFY_VALIDATE:
case MSIMODIFY_VALIDATE_FIELD:
case MSIMODIFY_VALIDATE_DELETE:
FIXME("%p %d %p - mode not implemented\n", view, eModifyMode, rec );
r = ERROR_CALL_NOT_IMPLEMENTED;
break;
default:
r = ERROR_INVALID_DATA;
}
return r;
}
static UINT TABLE_delete( struct tagMSIVIEW *view )