Commit 6e7303a7 authored by Piotr Caban's avatar Piotr Caban Committed by Alexandre Julliard

msi: Support UPDATE when MSITRANSFORM_ERROR_VIEWTRANSFORM flag is used.

parent 8bc835b4
...@@ -2188,6 +2188,38 @@ UINT TABLE_CreateView( MSIDATABASE *db, LPCWSTR name, MSIVIEW **view ) ...@@ -2188,6 +2188,38 @@ UINT TABLE_CreateView( MSIDATABASE *db, LPCWSTR name, MSIVIEW **view )
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
static WCHAR* create_key_string(MSITABLEVIEW *tv, MSIRECORD *rec)
{
DWORD i, p, len, key_len = 0;
WCHAR *key;
for (i = 0; i < tv->num_cols; i++)
{
if (!(tv->columns[i].type & MSITYPE_KEY))
continue;
if (MSI_RecordGetStringW( rec, i+1, NULL, &len ) == ERROR_SUCCESS)
key_len += len;
key_len++;
}
key = msi_alloc( key_len * sizeof(WCHAR) );
if(!key)
return NULL;
p = 0;
for (i = 0; i < tv->num_cols; i++)
{
if (!(tv->columns[i].type & MSITYPE_KEY))
continue;
if (p)
key[p++] = '\t';
len = key_len - p;
if (MSI_RecordGetStringW( rec, i+1, key + p, &len ) == ERROR_SUCCESS)
p += len;
}
return key;
}
static UINT msi_record_stream_name( const MSITABLEVIEW *tv, MSIRECORD *rec, LPWSTR name, UINT *len ) static UINT msi_record_stream_name( const MSITABLEVIEW *tv, MSIRECORD *rec, LPWSTR name, UINT *len )
{ {
UINT p = 0, l, i, r; UINT p = 0, l, i, r;
...@@ -2222,20 +2254,153 @@ static UINT msi_record_stream_name( const MSITABLEVIEW *tv, MSIRECORD *rec, LPWS ...@@ -2222,20 +2254,153 @@ static UINT msi_record_stream_name( const MSITABLEVIEW *tv, MSIRECORD *rec, LPWS
static UINT TransformView_fetch_int( MSIVIEW *view, UINT row, UINT col, UINT *val ) static UINT TransformView_fetch_int( MSIVIEW *view, UINT row, UINT col, UINT *val )
{ {
FIXME("\n"); return TABLE_fetch_int( view, row, col, val );
return ERROR_CALL_NOT_IMPLEMENTED;
} }
static UINT TransformView_fetch_stream( MSIVIEW *view, UINT row, UINT col, IStream **stm ) static UINT TransformView_fetch_stream( MSIVIEW *view, UINT row, UINT col, IStream **stm )
{ {
FIXME("\n"); return TABLE_fetch_stream( view, row, col, stm );
return ERROR_CALL_NOT_IMPLEMENTED;
} }
static UINT TransformView_set_row( MSIVIEW *view, UINT row, MSIRECORD *rec, UINT mask ) static UINT TransformView_set_row( MSIVIEW *view, UINT row, MSIRECORD *rec, UINT mask )
{ {
FIXME("\n"); static const WCHAR query_pfx[] =
return ERROR_CALL_NOT_IMPLEMENTED; L"INSERT INTO `_TransformView` (`Table`, `Column`, `Row`, `Data`, `Current`) VALUES ('";
MSITABLEVIEW *tv = (MSITABLEVIEW*)view;
WCHAR buf[256], *query = buf;
MSIRECORD *old_rec;
MSIQUERY *q;
WCHAR *key;
UINT i, p, r, len, qlen;
if (!wcscmp( tv->name, szColumns ))
{
ERR( "trying to modify existing column\n" );
return ERROR_INSTALL_TRANSFORM_FAILURE;
}
if (!wcscmp( tv->name, szTables ))
{
ERR( "trying to modify existing table\n" );
return ERROR_INSTALL_TRANSFORM_FAILURE;
}
key = create_key_string( tv, rec );
if (!key)
return ERROR_OUTOFMEMORY;
r = msi_view_get_row( tv->db, view, row, &old_rec );
if (r != ERROR_SUCCESS)
old_rec = NULL;
for (i = 0; i < tv->num_cols; i++)
{
if (!(mask & (1 << i)))
continue;
if (tv->columns[i].type & MSITYPE_KEY)
continue;
qlen = p = wcslen( query_pfx );
qlen += wcslen( tv->name ) + 3; /* strlen("','") */
qlen += wcslen( tv->columns[i].colname ) + 3;
qlen += wcslen( key ) + 3;
if (MSITYPE_IS_BINARY( tv->columns[i].type ))
r = msi_record_stream_name( tv, rec, NULL, &len );
else
r = MSI_RecordGetStringW( rec, i + 1, NULL, &len );
if (r != ERROR_SUCCESS)
{
if (old_rec)
msiobj_release( &old_rec->hdr );
msi_free( key );
return r;
}
qlen += len + 3;
if (old_rec && (r = MSI_RecordGetStringW( old_rec, i+1, NULL, &len )))
{
msiobj_release( &old_rec->hdr );
msi_free( key );
return r;
}
qlen += len + 3; /* strlen("')") + 1 */
if (qlen > ARRAY_SIZE(buf))
{
query = msi_alloc( qlen * sizeof(WCHAR) );
if (!query)
{
if (old_rec)
msiobj_release( &old_rec->hdr );
msi_free( key );
return ERROR_OUTOFMEMORY;
}
}
memcpy( query, query_pfx, p * sizeof(WCHAR) );
len = wcslen( tv->name );
memcpy( query + p, tv->name, len * sizeof(WCHAR) );
p += len;
query[p++] = '\'';
query[p++] = ',';
query[p++] = '\'';
len = wcslen( tv->columns[i].colname );
memcpy( query + p, tv->columns[i].colname, len * sizeof(WCHAR) );
p += len;
query[p++] = '\'';
query[p++] = ',';
query[p++] = '\'';
len = wcslen( key );
memcpy( query + p, key, len * sizeof(WCHAR) );
p += len;
query[p++] = '\'';
query[p++] = ',';
query[p++] = '\'';
len = qlen - p;
if (MSITYPE_IS_BINARY( tv->columns[i].type ))
msi_record_stream_name( tv, rec, query + p, &len );
else
MSI_RecordGetStringW( rec, i + 1, query + p, &len );
p += len;
query[p++] = '\'';
query[p++] = ',';
query[p++] = '\'';
if (old_rec)
{
len = qlen - p;
MSI_RecordGetStringW( old_rec, i + 1, query + p, &len );
p += len;
}
query[p++] = '\'';
query[p++] = ')';
query[p++] = 0;
r = MSI_DatabaseOpenViewW( tv->db, query, &q );
if (query != buf)
msi_free( query );
if (r != ERROR_SUCCESS)
{
if (old_rec)
msiobj_release( &old_rec->hdr );
msi_free( key );
return r;
}
r = MSI_ViewExecute( q, NULL );
msiobj_release( &q->hdr );
if (r != ERROR_SUCCESS)
{
if (old_rec)
msiobj_release( &old_rec->hdr );
msi_free( key );
return r;
}
}
if (old_rec)
msiobj_release( &old_rec->hdr );
msi_free( key );
return ERROR_SUCCESS;
} }
static UINT TransformView_insert_row( MSIVIEW *view, MSIRECORD *rec, UINT row, BOOL temporary ) static UINT TransformView_insert_row( MSIVIEW *view, MSIRECORD *rec, UINT row, BOOL temporary )
...@@ -2262,15 +2427,13 @@ static UINT TransformView_close( MSIVIEW *view ) ...@@ -2262,15 +2427,13 @@ static UINT TransformView_close( MSIVIEW *view )
static UINT TransformView_get_dimensions( MSIVIEW *view, UINT *rows, UINT *cols ) static UINT TransformView_get_dimensions( MSIVIEW *view, UINT *rows, UINT *cols )
{ {
FIXME("\n"); return TABLE_get_dimensions( view, rows, cols );
return ERROR_CALL_NOT_IMPLEMENTED;
} }
static UINT TransformView_get_column_info( MSIVIEW *view, UINT n, LPCWSTR *name, UINT *type, static UINT TransformView_get_column_info( MSIVIEW *view, UINT n, LPCWSTR *name, UINT *type,
BOOL *temporary, LPCWSTR *table_name ) BOOL *temporary, LPCWSTR *table_name )
{ {
FIXME("\n"); return TABLE_get_column_info( view, n, name, type, temporary, table_name );
return ERROR_CALL_NOT_IMPLEMENTED;
} }
static UINT TransformView_delete( MSIVIEW *view ) static UINT TransformView_delete( MSIVIEW *view )
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment