msi: Properly delete rows from the table, instead of zeroing out the row.
This commit is contained in:
parent
82f4e3981b
commit
9309f4dfa0
|
@ -130,6 +130,7 @@ static const MSIVIEWOPS alter_ops =
|
||||||
ALTER_fetch_stream,
|
ALTER_fetch_stream,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
|
NULL,
|
||||||
ALTER_execute,
|
ALTER_execute,
|
||||||
ALTER_close,
|
ALTER_close,
|
||||||
ALTER_get_dimensions,
|
ALTER_get_dimensions,
|
||||||
|
|
|
@ -124,6 +124,7 @@ static const MSIVIEWOPS create_ops =
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
|
NULL,
|
||||||
CREATE_execute,
|
CREATE_execute,
|
||||||
CREATE_close,
|
CREATE_close,
|
||||||
CREATE_get_dimensions,
|
CREATE_get_dimensions,
|
||||||
|
|
|
@ -185,6 +185,7 @@ static const MSIVIEWOPS delete_ops =
|
||||||
DELETE_fetch_stream,
|
DELETE_fetch_stream,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
|
NULL,
|
||||||
DELETE_execute,
|
DELETE_execute,
|
||||||
DELETE_close,
|
DELETE_close,
|
||||||
DELETE_get_dimensions,
|
DELETE_get_dimensions,
|
||||||
|
|
|
@ -274,6 +274,7 @@ static const MSIVIEWOPS distinct_ops =
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
|
NULL,
|
||||||
DISTINCT_execute,
|
DISTINCT_execute,
|
||||||
DISTINCT_close,
|
DISTINCT_close,
|
||||||
DISTINCT_get_dimensions,
|
DISTINCT_get_dimensions,
|
||||||
|
|
|
@ -225,6 +225,7 @@ static const MSIVIEWOPS insert_ops =
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
|
NULL,
|
||||||
INSERT_execute,
|
INSERT_execute,
|
||||||
INSERT_close,
|
INSERT_close,
|
||||||
INSERT_get_dimensions,
|
INSERT_get_dimensions,
|
||||||
|
|
|
@ -245,6 +245,7 @@ static const MSIVIEWOPS join_ops =
|
||||||
JOIN_fetch_stream,
|
JOIN_fetch_stream,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
|
NULL,
|
||||||
JOIN_execute,
|
JOIN_execute,
|
||||||
JOIN_close,
|
JOIN_close,
|
||||||
JOIN_get_dimensions,
|
JOIN_get_dimensions,
|
||||||
|
|
|
@ -148,6 +148,11 @@ typedef struct tagMSIVIEWOPS
|
||||||
*/
|
*/
|
||||||
UINT (*insert_row)( struct tagMSIVIEW *view, MSIRECORD *record, BOOL temporary );
|
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
|
* execute - loads the underlying data into memory so it can be read
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -274,6 +274,7 @@ static const MSIVIEWOPS order_ops =
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
|
NULL,
|
||||||
ORDER_execute,
|
ORDER_execute,
|
||||||
ORDER_close,
|
ORDER_close,
|
||||||
ORDER_get_dimensions,
|
ORDER_get_dimensions,
|
||||||
|
|
|
@ -267,6 +267,7 @@ static const MSIVIEWOPS select_ops =
|
||||||
SELECT_fetch_stream,
|
SELECT_fetch_stream,
|
||||||
SELECT_set_row,
|
SELECT_set_row,
|
||||||
SELECT_insert_row,
|
SELECT_insert_row,
|
||||||
|
NULL,
|
||||||
SELECT_execute,
|
SELECT_execute,
|
||||||
SELECT_close,
|
SELECT_close,
|
||||||
SELECT_get_dimensions,
|
SELECT_get_dimensions,
|
||||||
|
|
|
@ -204,6 +204,12 @@ done:
|
||||||
return r;
|
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)
|
static UINT STREAMS_execute(struct tagMSIVIEW *view, MSIRECORD *record)
|
||||||
{
|
{
|
||||||
TRACE("(%p, %p)\n", view, record);
|
TRACE("(%p, %p)\n", view, record);
|
||||||
|
@ -323,6 +329,7 @@ static const MSIVIEWOPS streams_ops =
|
||||||
STREAMS_fetch_stream,
|
STREAMS_fetch_stream,
|
||||||
STREAMS_set_row,
|
STREAMS_set_row,
|
||||||
STREAMS_insert_row,
|
STREAMS_insert_row,
|
||||||
|
STREAMS_delete_row,
|
||||||
STREAMS_execute,
|
STREAMS_execute,
|
||||||
STREAMS_close,
|
STREAMS_close,
|
||||||
STREAMS_get_dimensions,
|
STREAMS_get_dimensions,
|
||||||
|
|
|
@ -1476,6 +1476,35 @@ static UINT TABLE_insert_row( struct tagMSIVIEW *view, MSIRECORD *rec, BOOL temp
|
||||||
return TABLE_set_row( view, row, rec, (1<<tv->num_cols) - 1 );
|
return TABLE_set_row( view, row, rec, (1<<tv->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,
|
static UINT TABLE_modify( struct tagMSIVIEW *view, MSIMODIFY eModifyMode,
|
||||||
MSIRECORD *rec)
|
MSIRECORD *rec)
|
||||||
{
|
{
|
||||||
|
@ -1618,6 +1647,7 @@ static const MSIVIEWOPS table_ops =
|
||||||
TABLE_fetch_stream,
|
TABLE_fetch_stream,
|
||||||
TABLE_set_row,
|
TABLE_set_row,
|
||||||
TABLE_insert_row,
|
TABLE_insert_row,
|
||||||
|
TABLE_delete_row,
|
||||||
TABLE_execute,
|
TABLE_execute,
|
||||||
TABLE_close,
|
TABLE_close,
|
||||||
TABLE_get_dimensions,
|
TABLE_get_dimensions,
|
||||||
|
@ -1896,15 +1926,6 @@ static UINT msi_table_find_row( MSITABLEVIEW *tv, MSIRECORD *rec, UINT *row )
|
||||||
return r;
|
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,
|
static UINT msi_table_load_transform( MSIDATABASE *db, IStorage *stg,
|
||||||
string_table *st, LPCWSTR name )
|
string_table *st, LPCWSTR name )
|
||||||
{
|
{
|
||||||
|
@ -2028,7 +2049,7 @@ static UINT msi_table_load_transform( MSIDATABASE *db, IStorage *stg,
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
TRACE("deleting row [%d]:\n", row);
|
TRACE("deleting row [%d]:\n", row);
|
||||||
msi_delete_row( tv, row );
|
TABLE_delete_row( &tv->view, row );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if( TRACE_ON(msidb) ) dump_record( rec );
|
if( TRACE_ON(msidb) ) dump_record( rec );
|
||||||
|
|
|
@ -1872,7 +1872,7 @@ static const WCHAR data5[] = { /* _StringPool */
|
||||||
/* update row, 0x0002 is a bitmask of present column data, keys are excluded */
|
/* update row, 0x0002 is a bitmask of present column data, keys are excluded */
|
||||||
static const WCHAR data6[] = { /* MOO */
|
static const WCHAR data6[] = { /* MOO */
|
||||||
0x0002, 0x8001, 0x0001, /* update row */
|
0x0002, 0x8001, 0x0001, /* update row */
|
||||||
0x0000, 0x8003, /* delete row */
|
0x0000, 0x8002, /* delete row */
|
||||||
};
|
};
|
||||||
|
|
||||||
static const WCHAR data7[] = { /* BINARY */
|
static const WCHAR data7[] = { /* BINARY */
|
||||||
|
@ -1943,7 +1943,7 @@ static void generate_transform_manual(void)
|
||||||
|
|
||||||
static void test_try_transform(void)
|
static void test_try_transform(void)
|
||||||
{
|
{
|
||||||
MSIHANDLE hdb, hrec;
|
MSIHANDLE hdb, hview, hrec;
|
||||||
LPCSTR query;
|
LPCSTR query;
|
||||||
UINT r;
|
UINT r;
|
||||||
DWORD sz;
|
DWORD sz;
|
||||||
|
@ -2037,14 +2037,14 @@ static void test_try_transform(void)
|
||||||
|
|
||||||
/* check unchanged value */
|
/* check unchanged value */
|
||||||
hrec = 0;
|
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);
|
r = do_query(hdb, query, &hrec);
|
||||||
ok(r == ERROR_SUCCESS, "select query failed\n");
|
ok(r == ERROR_SUCCESS, "select query failed\n");
|
||||||
MsiCloseHandle(hrec);
|
MsiCloseHandle(hrec);
|
||||||
|
|
||||||
/* check deleted value */
|
/* check deleted value */
|
||||||
hrec = 0;
|
hrec = 0;
|
||||||
query = "select * from `MOO` where `NOO` = 3";
|
query = "select * from `MOO` where `NOO` = 2";
|
||||||
r = do_query(hdb, query, &hrec);
|
r = do_query(hdb, query, &hrec);
|
||||||
ok(r == ERROR_NO_MORE_ITEMS, "select query failed\n");
|
ok(r == ERROR_NO_MORE_ITEMS, "select query failed\n");
|
||||||
if (hrec) MsiCloseHandle(hrec);
|
if (hrec) MsiCloseHandle(hrec);
|
||||||
|
@ -2063,7 +2063,47 @@ static void test_try_transform(void)
|
||||||
ok(sz == 9, "stream data was wrong size\n");
|
ok(sz == 9, "stream data was wrong size\n");
|
||||||
if (hrec) MsiCloseHandle(hrec);
|
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(msifile);
|
||||||
DeleteFile(msifile2);
|
DeleteFile(msifile2);
|
||||||
|
|
|
@ -177,6 +177,7 @@ static const MSIVIEWOPS update_ops =
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
|
NULL,
|
||||||
UPDATE_execute,
|
UPDATE_execute,
|
||||||
UPDATE_close,
|
UPDATE_close,
|
||||||
UPDATE_get_dimensions,
|
UPDATE_get_dimensions,
|
||||||
|
|
|
@ -439,6 +439,7 @@ static const MSIVIEWOPS where_ops =
|
||||||
WHERE_fetch_stream,
|
WHERE_fetch_stream,
|
||||||
WHERE_set_row,
|
WHERE_set_row,
|
||||||
NULL,
|
NULL,
|
||||||
|
NULL,
|
||||||
WHERE_execute,
|
WHERE_execute,
|
||||||
WHERE_close,
|
WHERE_close,
|
||||||
WHERE_get_dimensions,
|
WHERE_get_dimensions,
|
||||||
|
|
Loading…
Reference in New Issue