mirror of
https://github.com/reactos/reactos.git
synced 2025-05-29 05:58:13 +00:00
[WINESYNC] msi: Support UPDATE when MSITRANSFORM_ERROR_VIEWTRANSFORM flag is used.
Signed-off-by: Piotr Caban <piotr@codeweavers.com> Signed-off-by: Hans Leidekker <hans@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org> wine commit id 6e7303a7006538d3df1a09e13f5a5f469098b35f by Piotr Caban <piotr@codeweavers.com>
This commit is contained in:
parent
1bbb87bb26
commit
317c1f6c05
1 changed files with 173 additions and 10 deletions
|
@ -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
|
||||||
|
|
||||||
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 )
|
||||||
|
|
||||||
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 )
|
||||||
|
|
Loading…
Reference in a new issue