diff --git a/dlls/msi/alter.c b/dlls/msi/alter.c index 58a6099cd02..b506aa1e8cb 100644 --- a/dlls/msi/alter.c +++ b/dlls/msi/alter.c @@ -130,6 +130,7 @@ static const MSIVIEWOPS alter_ops = ALTER_fetch_stream, NULL, NULL, + NULL, ALTER_execute, ALTER_close, ALTER_get_dimensions, diff --git a/dlls/msi/create.c b/dlls/msi/create.c index 965a4a6049c..9c3fb394e28 100644 --- a/dlls/msi/create.c +++ b/dlls/msi/create.c @@ -124,6 +124,7 @@ static const MSIVIEWOPS create_ops = NULL, NULL, NULL, + NULL, CREATE_execute, CREATE_close, CREATE_get_dimensions, diff --git a/dlls/msi/delete.c b/dlls/msi/delete.c index 1484f6a61e1..bd33956cccf 100644 --- a/dlls/msi/delete.c +++ b/dlls/msi/delete.c @@ -185,6 +185,7 @@ static const MSIVIEWOPS delete_ops = DELETE_fetch_stream, NULL, NULL, + NULL, DELETE_execute, DELETE_close, DELETE_get_dimensions, diff --git a/dlls/msi/distinct.c b/dlls/msi/distinct.c index a00f274a5c4..851382313ba 100644 --- a/dlls/msi/distinct.c +++ b/dlls/msi/distinct.c @@ -274,6 +274,7 @@ static const MSIVIEWOPS distinct_ops = NULL, NULL, NULL, + NULL, DISTINCT_execute, DISTINCT_close, DISTINCT_get_dimensions, diff --git a/dlls/msi/insert.c b/dlls/msi/insert.c index 48706ea066a..95c35f38a19 100644 --- a/dlls/msi/insert.c +++ b/dlls/msi/insert.c @@ -225,6 +225,7 @@ static const MSIVIEWOPS insert_ops = NULL, NULL, NULL, + NULL, INSERT_execute, INSERT_close, INSERT_get_dimensions, diff --git a/dlls/msi/join.c b/dlls/msi/join.c index b384630c2e2..ab1935ee2ac 100644 --- a/dlls/msi/join.c +++ b/dlls/msi/join.c @@ -245,6 +245,7 @@ static const MSIVIEWOPS join_ops = JOIN_fetch_stream, NULL, NULL, + NULL, JOIN_execute, JOIN_close, JOIN_get_dimensions, diff --git a/dlls/msi/msipriv.h b/dlls/msi/msipriv.h index fd61b5c88b7..e577fc59570 100644 --- a/dlls/msi/msipriv.h +++ b/dlls/msi/msipriv.h @@ -148,6 +148,11 @@ typedef struct tagMSIVIEWOPS */ UINT (*insert_row)( struct tagMSIVIEW *view, MSIRECORD *record, BOOL temporary ); + /* + * Deletes a row from the database + */ + UINT (*delete_row)( struct tagMSIVIEW *view, UINT row ); + /* * execute - loads the underlying data into memory so it can be read */ diff --git a/dlls/msi/order.c b/dlls/msi/order.c index 82b12698405..c0ab643a15f 100644 --- a/dlls/msi/order.c +++ b/dlls/msi/order.c @@ -274,6 +274,7 @@ static const MSIVIEWOPS order_ops = NULL, NULL, NULL, + NULL, ORDER_execute, ORDER_close, ORDER_get_dimensions, diff --git a/dlls/msi/select.c b/dlls/msi/select.c index 44999e36423..6953e1f0fc5 100644 --- a/dlls/msi/select.c +++ b/dlls/msi/select.c @@ -267,6 +267,7 @@ static const MSIVIEWOPS select_ops = SELECT_fetch_stream, SELECT_set_row, SELECT_insert_row, + NULL, SELECT_execute, SELECT_close, SELECT_get_dimensions, diff --git a/dlls/msi/streams.c b/dlls/msi/streams.c index 611f9978a57..fbb8b793df9 100644 --- a/dlls/msi/streams.c +++ b/dlls/msi/streams.c @@ -204,6 +204,12 @@ done: return r; } +static UINT STREAMS_delete_row(struct tagMSIVIEW *view, UINT row) +{ + FIXME("(%p %d): stub!\n", view, row); + return ERROR_SUCCESS; +} + static UINT STREAMS_execute(struct tagMSIVIEW *view, MSIRECORD *record) { TRACE("(%p, %p)\n", view, record); @@ -323,6 +329,7 @@ static const MSIVIEWOPS streams_ops = STREAMS_fetch_stream, STREAMS_set_row, STREAMS_insert_row, + STREAMS_delete_row, STREAMS_execute, STREAMS_close, STREAMS_get_dimensions, diff --git a/dlls/msi/table.c b/dlls/msi/table.c index c9b15728575..cf706d8adf2 100644 --- a/dlls/msi/table.c +++ b/dlls/msi/table.c @@ -1476,6 +1476,35 @@ static UINT TABLE_insert_row( struct tagMSIVIEW *view, MSIRECORD *rec, BOOL temp return TABLE_set_row( view, row, rec, (1<num_cols) - 1 ); } +static UINT TABLE_delete_row( struct tagMSIVIEW *view, UINT row ) +{ + MSITABLEVIEW *tv = (MSITABLEVIEW*)view; + UINT r, num_rows, num_cols; + BYTE *src, *dest; + + TRACE("%p %d\n", tv, row); + + if ( !tv->table ) + return ERROR_INVALID_PARAMETER; + + r = TABLE_get_dimensions( view, &num_rows, &num_cols ); + if ( r != ERROR_SUCCESS ) + return r; + + if ( row >= num_rows ) + return ERROR_FUNCTION_FAILED; + + tv->table->row_count--; + + if ( row == num_rows - 1 ) + return ERROR_SUCCESS; + + dest = tv->table->data[row]; + src = tv->table->data[row + 1]; + memmove(dest, src, (num_rows - row - 1) * tv->row_size); + return ERROR_SUCCESS; +} + static UINT TABLE_modify( struct tagMSIVIEW *view, MSIMODIFY eModifyMode, MSIRECORD *rec) { @@ -1618,6 +1647,7 @@ static const MSIVIEWOPS table_ops = TABLE_fetch_stream, TABLE_set_row, TABLE_insert_row, + TABLE_delete_row, TABLE_execute, TABLE_close, TABLE_get_dimensions, @@ -1896,15 +1926,6 @@ static UINT msi_table_find_row( MSITABLEVIEW *tv, MSIRECORD *rec, UINT *row ) return r; } -static UINT msi_delete_row( MSITABLEVIEW *tv, UINT row ) -{ - UINT i; - - for( i=1; i<=tv->num_cols; i++ ) - TABLE_set_int( tv, row, i, 0 ); - return ERROR_SUCCESS; -} - static UINT msi_table_load_transform( MSIDATABASE *db, IStorage *stg, string_table *st, LPCWSTR name ) { @@ -2028,7 +2049,7 @@ static UINT msi_table_load_transform( MSIDATABASE *db, IStorage *stg, else { TRACE("deleting row [%d]:\n", row); - msi_delete_row( tv, row ); + TABLE_delete_row( &tv->view, row ); } } if( TRACE_ON(msidb) ) dump_record( rec ); diff --git a/dlls/msi/tests/db.c b/dlls/msi/tests/db.c index 9f985407db5..2f4cc767bdb 100644 --- a/dlls/msi/tests/db.c +++ b/dlls/msi/tests/db.c @@ -1872,7 +1872,7 @@ static const WCHAR data5[] = { /* _StringPool */ /* update row, 0x0002 is a bitmask of present column data, keys are excluded */ static const WCHAR data6[] = { /* MOO */ 0x0002, 0x8001, 0x0001, /* update row */ - 0x0000, 0x8003, /* delete row */ + 0x0000, 0x8002, /* delete row */ }; static const WCHAR data7[] = { /* BINARY */ @@ -1943,7 +1943,7 @@ static void generate_transform_manual(void) static void test_try_transform(void) { - MSIHANDLE hdb, hrec; + MSIHANDLE hdb, hview, hrec; LPCSTR query; UINT r; DWORD sz; @@ -2037,14 +2037,14 @@ static void test_try_transform(void) /* check unchanged value */ hrec = 0; - query = "select `NOO`,`OOO` from `MOO` where `NOO` = 2 AND `OOO` = 'b'"; + query = "select `NOO`,`OOO` from `MOO` where `NOO` = 3 AND `OOO` = 'c'"; r = do_query(hdb, query, &hrec); ok(r == ERROR_SUCCESS, "select query failed\n"); MsiCloseHandle(hrec); /* check deleted value */ hrec = 0; - query = "select * from `MOO` where `NOO` = 3"; + query = "select * from `MOO` where `NOO` = 2"; r = do_query(hdb, query, &hrec); ok(r == ERROR_NO_MORE_ITEMS, "select query failed\n"); if (hrec) MsiCloseHandle(hrec); @@ -2063,7 +2063,47 @@ static void test_try_transform(void) ok(sz == 9, "stream data was wrong size\n"); if (hrec) MsiCloseHandle(hrec); - MsiCloseHandle( hdb ); + /* check the validity of the table with a deleted row */ + hrec = 0; + query = "select * from `MOO`"; + r = MsiDatabaseOpenView(hdb, query, &hview); + ok(r == ERROR_SUCCESS, "open view failed\n"); + + r = MsiViewExecute(hview, 0); + ok(r == ERROR_SUCCESS, "view execute failed\n"); + + r = MsiViewFetch(hview, &hrec); + ok(r == ERROR_SUCCESS, "view fetch failed\n"); + + r = MsiRecordGetInteger(hrec, 1); + ok(r == 1, "Expected 1, got %d\n", r); + + sz = sizeof buffer; + r = MsiRecordGetString(hrec, 2, buffer, &sz); + ok(r == ERROR_SUCCESS, "record get string failed\n"); + ok(!lstrcmpA(buffer, "c"), "Expected c, got %s\n", buffer); + + MsiCloseHandle(hrec); + + r = MsiViewFetch(hview, &hrec); + ok(r == ERROR_SUCCESS, "view fetch failed\n"); + + r = MsiRecordGetInteger(hrec, 1); + ok(r == 3, "Expected 3, got %d\n", r); + + sz = sizeof buffer; + r = MsiRecordGetString(hrec, 2, buffer, &sz); + ok(r == ERROR_SUCCESS, "record get string failed\n"); + ok(!lstrcmpA(buffer, "c"), "Expected b, got %s\n", buffer); + + MsiCloseHandle(hrec); + + r = MsiViewFetch(hview, &hrec); + ok(r == ERROR_NO_MORE_ITEMS, "view fetch succeeded\n"); + + MsiCloseHandle(hrec); + MsiCloseHandle(hview); + MsiCloseHandle(hdb); DeleteFile(msifile); DeleteFile(msifile2); diff --git a/dlls/msi/update.c b/dlls/msi/update.c index 6b9b3cfea66..bc3fb2ed15e 100644 --- a/dlls/msi/update.c +++ b/dlls/msi/update.c @@ -177,6 +177,7 @@ static const MSIVIEWOPS update_ops = NULL, NULL, NULL, + NULL, UPDATE_execute, UPDATE_close, UPDATE_get_dimensions, diff --git a/dlls/msi/where.c b/dlls/msi/where.c index 78056e1f647..ab9c9a6b2f1 100644 --- a/dlls/msi/where.c +++ b/dlls/msi/where.c @@ -439,6 +439,7 @@ static const MSIVIEWOPS where_ops = WHERE_fetch_stream, WHERE_set_row, NULL, + NULL, WHERE_execute, WHERE_close, WHERE_get_dimensions,