@@ -2188,6 +2188,38 @@ UINT TABLE_CreateView( MSIDATABASE *db, LPCWSTR name, MSIVIEW **view )
21882188 return ERROR_SUCCESS ;
21892189}
21902190
2191+ static WCHAR * create_key_string (MSITABLEVIEW * tv , MSIRECORD * rec )
2192+ {
2193+ DWORD i , p , len , key_len = 0 ;
2194+ WCHAR * key ;
2195+
2196+ for (i = 0 ; i < tv -> num_cols ; i ++ )
2197+ {
2198+ if (!(tv -> columns [i ].type & MSITYPE_KEY ))
2199+ continue ;
2200+ if (MSI_RecordGetStringW ( rec , i + 1 , NULL , & len ) == ERROR_SUCCESS )
2201+ key_len += len ;
2202+ key_len ++ ;
2203+ }
2204+
2205+ key = msi_alloc ( key_len * sizeof (WCHAR ) );
2206+ if (!key )
2207+ return NULL ;
2208+
2209+ p = 0 ;
2210+ for (i = 0 ; i < tv -> num_cols ; i ++ )
2211+ {
2212+ if (!(tv -> columns [i ].type & MSITYPE_KEY ))
2213+ continue ;
2214+ if (p )
2215+ key [p ++ ] = '\t' ;
2216+ len = key_len - p ;
2217+ if (MSI_RecordGetStringW ( rec , i + 1 , key + p , & len ) == ERROR_SUCCESS )
2218+ p += len ;
2219+ }
2220+ return key ;
2221+ }
2222+
21912223static UINT msi_record_stream_name ( const MSITABLEVIEW * tv , MSIRECORD * rec , LPWSTR name , UINT * len )
21922224{
21932225 UINT p = 0 , l , i , r ;
@@ -2222,20 +2254,153 @@ static UINT msi_record_stream_name( const MSITABLEVIEW *tv, MSIRECORD *rec, LPWS
22222254
22232255static UINT TransformView_fetch_int ( MSIVIEW * view , UINT row , UINT col , UINT * val )
22242256{
2225- FIXME ("\n" );
2226- return ERROR_CALL_NOT_IMPLEMENTED ;
2257+ return TABLE_fetch_int ( view , row , col , val );
22272258}
22282259
22292260static UINT TransformView_fetch_stream ( MSIVIEW * view , UINT row , UINT col , IStream * * stm )
22302261{
2231- FIXME ("\n" );
2232- return ERROR_CALL_NOT_IMPLEMENTED ;
2262+ return TABLE_fetch_stream ( view , row , col , stm );
22332263}
22342264
22352265static UINT TransformView_set_row ( MSIVIEW * view , UINT row , MSIRECORD * rec , UINT mask )
22362266{
2237- FIXME ("\n" );
2238- return ERROR_CALL_NOT_IMPLEMENTED ;
2267+ static const WCHAR query_pfx [] =
2268+ L"INSERT INTO `_TransformView` (`Table`, `Column`, `Row`, `Data`, `Current`) VALUES ('" ;
2269+
2270+ MSITABLEVIEW * tv = (MSITABLEVIEW * )view ;
2271+ WCHAR buf [256 ], * query = buf ;
2272+ MSIRECORD * old_rec ;
2273+ MSIQUERY * q ;
2274+ WCHAR * key ;
2275+ UINT i , p , r , len , qlen ;
2276+
2277+ if (!wcscmp ( tv -> name , szColumns ))
2278+ {
2279+ ERR ( "trying to modify existing column\n" );
2280+ return ERROR_INSTALL_TRANSFORM_FAILURE ;
2281+ }
2282+
2283+ if (!wcscmp ( tv -> name , szTables ))
2284+ {
2285+ ERR ( "trying to modify existing table\n" );
2286+ return ERROR_INSTALL_TRANSFORM_FAILURE ;
2287+ }
2288+
2289+ key = create_key_string ( tv , rec );
2290+ if (!key )
2291+ return ERROR_OUTOFMEMORY ;
2292+
2293+ r = msi_view_get_row ( tv -> db , view , row , & old_rec );
2294+ if (r != ERROR_SUCCESS )
2295+ old_rec = NULL ;
2296+
2297+ for (i = 0 ; i < tv -> num_cols ; i ++ )
2298+ {
2299+ if (!(mask & (1 << i )))
2300+ continue ;
2301+ if (tv -> columns [i ].type & MSITYPE_KEY )
2302+ continue ;
2303+
2304+ qlen = p = wcslen ( query_pfx );
2305+ qlen += wcslen ( tv -> name ) + 3 ; /* strlen("','") */
2306+ qlen += wcslen ( tv -> columns [i ].colname ) + 3 ;
2307+ qlen += wcslen ( key ) + 3 ;
2308+ if (MSITYPE_IS_BINARY ( tv -> columns [i ].type ))
2309+ r = msi_record_stream_name ( tv , rec , NULL , & len );
2310+ else
2311+ r = MSI_RecordGetStringW ( rec , i + 1 , NULL , & len );
2312+ if (r != ERROR_SUCCESS )
2313+ {
2314+ if (old_rec )
2315+ msiobj_release ( & old_rec -> hdr );
2316+ msi_free ( key );
2317+ return r ;
2318+ }
2319+ qlen += len + 3 ;
2320+ if (old_rec && (r = MSI_RecordGetStringW ( old_rec , i + 1 , NULL , & len )))
2321+ {
2322+ msiobj_release ( & old_rec -> hdr );
2323+ msi_free ( key );
2324+ return r ;
2325+ }
2326+ qlen += len + 3 ; /* strlen("')") + 1 */
2327+
2328+ if (qlen > ARRAY_SIZE (buf ))
2329+ {
2330+ query = msi_alloc ( qlen * sizeof (WCHAR ) );
2331+ if (!query )
2332+ {
2333+ if (old_rec )
2334+ msiobj_release ( & old_rec -> hdr );
2335+ msi_free ( key );
2336+ return ERROR_OUTOFMEMORY ;
2337+ }
2338+ }
2339+
2340+ memcpy ( query , query_pfx , p * sizeof (WCHAR ) );
2341+ len = wcslen ( tv -> name );
2342+ memcpy ( query + p , tv -> name , len * sizeof (WCHAR ) );
2343+ p += len ;
2344+ query [p ++ ] = '\'' ;
2345+ query [p ++ ] = ',' ;
2346+ query [p ++ ] = '\'' ;
2347+ len = wcslen ( tv -> columns [i ].colname );
2348+ memcpy ( query + p , tv -> columns [i ].colname , len * sizeof (WCHAR ) );
2349+ p += len ;
2350+ query [p ++ ] = '\'' ;
2351+ query [p ++ ] = ',' ;
2352+ query [p ++ ] = '\'' ;
2353+ len = wcslen ( key );
2354+ memcpy ( query + p , key , len * sizeof (WCHAR ) );
2355+ p += len ;
2356+ query [p ++ ] = '\'' ;
2357+ query [p ++ ] = ',' ;
2358+ query [p ++ ] = '\'' ;
2359+ len = qlen - p ;
2360+ if (MSITYPE_IS_BINARY ( tv -> columns [i ].type ))
2361+ msi_record_stream_name ( tv , rec , query + p , & len );
2362+ else
2363+ MSI_RecordGetStringW ( rec , i + 1 , query + p , & len );
2364+ p += len ;
2365+ query [p ++ ] = '\'' ;
2366+ query [p ++ ] = ',' ;
2367+ query [p ++ ] = '\'' ;
2368+ if (old_rec )
2369+ {
2370+ len = qlen - p ;
2371+ MSI_RecordGetStringW ( old_rec , i + 1 , query + p , & len );
2372+ p += len ;
2373+ }
2374+ query [p ++ ] = '\'' ;
2375+ query [p ++ ] = ')' ;
2376+ query [p ++ ] = 0 ;
2377+
2378+ r = MSI_DatabaseOpenViewW ( tv -> db , query , & q );
2379+ if (query != buf )
2380+ msi_free ( query );
2381+ if (r != ERROR_SUCCESS )
2382+ {
2383+ if (old_rec )
2384+ msiobj_release ( & old_rec -> hdr );
2385+ msi_free ( key );
2386+ return r ;
2387+ }
2388+
2389+ r = MSI_ViewExecute ( q , NULL );
2390+ msiobj_release ( & q -> hdr );
2391+ if (r != ERROR_SUCCESS )
2392+ {
2393+ if (old_rec )
2394+ msiobj_release ( & old_rec -> hdr );
2395+ msi_free ( key );
2396+ return r ;
2397+ }
2398+ }
2399+
2400+ if (old_rec )
2401+ msiobj_release ( & old_rec -> hdr );
2402+ msi_free ( key );
2403+ return ERROR_SUCCESS ;
22392404}
22402405
22412406static UINT TransformView_insert_row ( MSIVIEW * view , MSIRECORD * rec , UINT row , BOOL temporary )
@@ -2262,15 +2427,13 @@ static UINT TransformView_close( MSIVIEW *view )
22622427
22632428static UINT TransformView_get_dimensions ( MSIVIEW * view , UINT * rows , UINT * cols )
22642429{
2265- FIXME ("\n" );
2266- return ERROR_CALL_NOT_IMPLEMENTED ;
2430+ return TABLE_get_dimensions ( view , rows , cols );
22672431}
22682432
22692433static UINT TransformView_get_column_info ( MSIVIEW * view , UINT n , LPCWSTR * name , UINT * type ,
22702434 BOOL * temporary , LPCWSTR * table_name )
22712435{
2272- FIXME ("\n" );
2273- return ERROR_CALL_NOT_IMPLEMENTED ;
2436+ return TABLE_get_column_info ( view , n , name , type , temporary , table_name );
22742437}
22752438
22762439static UINT TransformView_delete ( MSIVIEW * view )
0 commit comments