@@ -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+
24552508static 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
24932549static 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
25212580UINT 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