Skip to content

Commit 28c50c1

Browse files
winesynclearn-more
authored andcommitted
[WINESYNC] msi: Support ALTER TABLE when MSITRANSFORM_ERROR_VIEWTRANSFORM flag is used.
Signed-off-by: Piotr Caban <[email protected]> Signed-off-by: Hans Leidekker <[email protected]> Signed-off-by: Alexandre Julliard <[email protected]> wine commit id ae6fd7b14792b932832da6f5d5088d500723c386 by Piotr Caban <[email protected]>
1 parent 27a430b commit 28c50c1

File tree

1 file changed

+149
-3
lines changed

1 file changed

+149
-3
lines changed

dll/win32/msi/table.c

Lines changed: 149 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2256,7 +2256,7 @@ static UINT TransformView_fetch_int( MSIVIEW *view, UINT row, UINT col, UINT *va
22562256
{
22572257
MSITABLEVIEW *tv = (MSITABLEVIEW*)view;
22582258

2259-
if (!tv->table)
2259+
if (!tv->table || col > tv->table->col_count)
22602260
{
22612261
*val = 0;
22622262
return ERROR_SUCCESS;
@@ -2268,7 +2268,7 @@ static UINT TransformView_fetch_stream( MSIVIEW *view, UINT row, UINT col, IStre
22682268
{
22692269
MSITABLEVIEW *tv = (MSITABLEVIEW*)view;
22702270

2271-
if (!tv->table)
2271+
if (!tv->table || col > tv->table->col_count)
22722272
{
22732273
*stm = NULL;
22742274
return ERROR_SUCCESS;
@@ -2452,13 +2452,69 @@ static UINT TransformView_create_table( MSITABLEVIEW *tv, MSIRECORD *rec )
24522452
return r;
24532453
}
24542454

2455+
static UINT TransformView_add_column( MSITABLEVIEW *tv, MSIRECORD *rec )
2456+
{
2457+
static const WCHAR query_pfx[] =
2458+
L"INSERT INTO `_TransformView` (`Table`, `Current`, `Column`, `Data`) VALUES ('";
2459+
2460+
WCHAR buf[256], *query = buf;
2461+
UINT i, p, len, r, qlen;
2462+
MSIQUERY *q;
2463+
2464+
qlen = p = wcslen( query_pfx );
2465+
for (i = 1; i <= 4; i++)
2466+
{
2467+
r = MSI_RecordGetStringW( rec, i, NULL, &len );
2468+
if (r != ERROR_SUCCESS)
2469+
return r;
2470+
qlen += len + 3; /* strlen( "','" ) */
2471+
}
2472+
2473+
if (qlen > ARRAY_SIZE(buf))
2474+
{
2475+
query = msi_alloc( len * sizeof(WCHAR) );
2476+
qlen = len;
2477+
if (!query)
2478+
return ERROR_OUTOFMEMORY;
2479+
}
2480+
2481+
memcpy( query, query_pfx, p * sizeof(WCHAR) );
2482+
for (i = 1; i <= 4; i++)
2483+
{
2484+
len = qlen - p;
2485+
MSI_RecordGetStringW( rec, i, query + p, &len );
2486+
p += len;
2487+
query[p++] = '\'';
2488+
if (i != 4)
2489+
{
2490+
query[p++] = ',';
2491+
query[p++] = '\'';
2492+
}
2493+
}
2494+
query[p++] = ')';
2495+
query[p++] = 0;
2496+
2497+
r = MSI_DatabaseOpenViewW( tv->db, query, &q );
2498+
if (query != buf)
2499+
msi_free( query );
2500+
if (r != ERROR_SUCCESS)
2501+
return r;
2502+
2503+
r = MSI_ViewExecute( q, NULL );
2504+
msiobj_release( &q->hdr );
2505+
return r;
2506+
}
2507+
24552508
static UINT TransformView_insert_row( MSIVIEW *view, MSIRECORD *rec, UINT row, BOOL temporary )
24562509
{
24572510
MSITABLEVIEW *tv = (MSITABLEVIEW*)view;
24582511

24592512
if (!wcscmp(tv->name, szTables))
24602513
return TransformView_create_table( tv, rec );
24612514

2515+
if (!wcscmp(tv->name, szColumns))
2516+
return TransformView_add_column( tv, rec );
2517+
24622518
FIXME("\n");
24632519
return ERROR_CALL_NOT_IMPLEMENTED;
24642520
}
@@ -2492,6 +2548,9 @@ static UINT TransformView_get_column_info( MSIVIEW *view, UINT n, LPCWSTR *name,
24922548

24932549
static UINT TransformView_delete( MSIVIEW *view )
24942550
{
2551+
MSITABLEVIEW *tv = (MSITABLEVIEW*)view;
2552+
if (!tv->table || tv->columns != tv->table->colinfo)
2553+
msi_free( tv->columns );
24952554
return TABLE_delete( view );
24962555
}
24972556

@@ -2520,8 +2579,15 @@ static const MSIVIEWOPS transform_view_ops =
25202579

25212580
UINT TransformView_Create( MSIDATABASE *db, string_table *st, LPCWSTR name, MSIVIEW **view )
25222581
{
2523-
UINT r, name_len, size;
2582+
static const WCHAR query_pfx[] = L"SELECT `Column`, `Data`, `Current` FROM `_TransformView` WHERE `Table`='";
2583+
static const WCHAR query_sfx[] = L"' AND `Row` IS NULL AND `Current` IS NOT NULL";
2584+
2585+
WCHAR buf[256], *query = buf;
2586+
UINT r, len, name_len, size, add_col;
2587+
MSICOLUMNINFO *colinfo;
25242588
MSITABLEVIEW *tv;
2589+
MSIRECORD *rec;
2590+
MSIQUERY *q;
25252591

25262592
name_len = wcslen( name );
25272593

@@ -2548,6 +2614,86 @@ UINT TransformView_Create( MSIDATABASE *db, string_table *st, LPCWSTR name, MSIV
25482614
}
25492615

25502616
tv->view.ops = &transform_view_ops;
2617+
2618+
len = ARRAY_SIZE(query_pfx) + name_len + ARRAY_SIZE(query_sfx) - 1;
2619+
if (len > ARRAY_SIZE(buf))
2620+
{
2621+
query = msi_alloc( len * sizeof(WCHAR) );
2622+
if (!query)
2623+
{
2624+
msi_free( tv );
2625+
return ERROR_OUTOFMEMORY;
2626+
}
2627+
}
2628+
memcpy( query, query_pfx, ARRAY_SIZE(query_pfx) * sizeof(WCHAR) );
2629+
len = ARRAY_SIZE(query_pfx) - 1;
2630+
memcpy( query + len, name, name_len * sizeof(WCHAR) );
2631+
len += name_len;
2632+
memcpy( query + len, query_sfx, ARRAY_SIZE(query_sfx) * sizeof(WCHAR) );
2633+
2634+
r = MSI_DatabaseOpenViewW( tv->db, query, &q );
2635+
if (query != buf)
2636+
msi_free( query );
2637+
if (r != ERROR_SUCCESS)
2638+
{
2639+
msi_free( tv );
2640+
return r;
2641+
}
2642+
2643+
r = MSI_ViewExecute( q, NULL );
2644+
if (r != ERROR_SUCCESS)
2645+
{
2646+
msi_free( tv );
2647+
return r;
2648+
}
2649+
2650+
r = q->view->ops->get_dimensions( q->view, &add_col, NULL );
2651+
if (r != ERROR_SUCCESS)
2652+
{
2653+
MSI_ViewClose( q );
2654+
msiobj_release( &q->hdr );
2655+
msi_free( tv );
2656+
return r;
2657+
}
2658+
if (!add_col)
2659+
{
2660+
MSI_ViewClose( q );
2661+
msiobj_release( &q->hdr );
2662+
return ERROR_SUCCESS;
2663+
}
2664+
2665+
colinfo = msi_alloc_zero( (add_col + tv->num_cols) * sizeof(*colinfo) );
2666+
if (!colinfo)
2667+
{
2668+
MSI_ViewClose( q );
2669+
msiobj_release( &q->hdr );
2670+
msi_free( tv );
2671+
return r;
2672+
}
2673+
2674+
while (MSI_ViewFetch( q, &rec ) == ERROR_SUCCESS)
2675+
{
2676+
int name_len;
2677+
const WCHAR *name = msi_record_get_string( rec, 1, &name_len );
2678+
const WCHAR *type = msi_record_get_string( rec, 2, NULL );
2679+
UINT name_id, idx;
2680+
2681+
idx = _wtoi( msi_record_get_string(rec, 3, NULL) );
2682+
colinfo[idx - 1].number = idx;
2683+
colinfo[idx - 1].type = _wtoi( type );
2684+
2685+
r = msi_string2id( st, name, name_len, &name_id );
2686+
if (r == ERROR_SUCCESS)
2687+
colinfo[idx - 1].colname = msi_string_lookup( st, name_id, NULL );
2688+
else
2689+
ERR( "column name %s is not defined in strings table\n", wine_dbgstr_w(name) );
2690+
}
2691+
MSI_ViewClose( q );
2692+
msiobj_release( &q->hdr );
2693+
2694+
memcpy( colinfo, tv->columns, tv->num_cols * sizeof(*colinfo) );
2695+
tv->columns = colinfo;
2696+
tv->num_cols += add_col;
25512697
return ERROR_SUCCESS;
25522698
}
25532699

0 commit comments

Comments
 (0)