msi: Test and implement the MSIMODIFY_DELETE command.
This commit is contained in:
parent
341d1fa7b5
commit
35a6782d7b
|
@ -567,6 +567,7 @@ UINT WINAPI MsiViewGetColumnInfo(MSIHANDLE hView, MSICOLINFO info, MSIHANDLE *hR
|
||||||
UINT MSI_ViewModify( MSIQUERY *query, MSIMODIFY mode, MSIRECORD *rec )
|
UINT MSI_ViewModify( MSIQUERY *query, MSIMODIFY mode, MSIRECORD *rec )
|
||||||
{
|
{
|
||||||
MSIVIEW *view = NULL;
|
MSIVIEW *view = NULL;
|
||||||
|
UINT r;
|
||||||
|
|
||||||
if ( !query || !rec )
|
if ( !query || !rec )
|
||||||
return ERROR_INVALID_HANDLE;
|
return ERROR_INVALID_HANDLE;
|
||||||
|
@ -575,7 +576,11 @@ UINT MSI_ViewModify( MSIQUERY *query, MSIMODIFY mode, MSIRECORD *rec )
|
||||||
if ( !view || !view->ops->modify)
|
if ( !view || !view->ops->modify)
|
||||||
return ERROR_FUNCTION_FAILED;
|
return ERROR_FUNCTION_FAILED;
|
||||||
|
|
||||||
return view->ops->modify( view, mode, rec, query->row );
|
r = view->ops->modify( view, mode, rec, query->row );
|
||||||
|
if (mode == MSIMODIFY_DELETE && r == ERROR_SUCCESS)
|
||||||
|
query->row--;
|
||||||
|
|
||||||
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
UINT WINAPI MsiViewModify( MSIHANDLE hView, MSIMODIFY eModifyMode,
|
UINT WINAPI MsiViewModify( MSIHANDLE hView, MSIMODIFY eModifyMode,
|
||||||
|
|
|
@ -1518,8 +1518,7 @@ static UINT TABLE_insert_row( struct tagMSIVIEW *view, MSIRECORD *rec, BOOL temp
|
||||||
static UINT TABLE_delete_row( struct tagMSIVIEW *view, UINT row )
|
static UINT TABLE_delete_row( struct tagMSIVIEW *view, UINT row )
|
||||||
{
|
{
|
||||||
MSITABLEVIEW *tv = (MSITABLEVIEW*)view;
|
MSITABLEVIEW *tv = (MSITABLEVIEW*)view;
|
||||||
UINT r, num_rows, num_cols;
|
UINT r, num_rows, num_cols, i;
|
||||||
BYTE *src, *dest;
|
|
||||||
|
|
||||||
TRACE("%p %d\n", tv, row);
|
TRACE("%p %d\n", tv, row);
|
||||||
|
|
||||||
|
@ -1538,9 +1537,9 @@ static UINT TABLE_delete_row( struct tagMSIVIEW *view, UINT row )
|
||||||
if ( row == num_rows - 1 )
|
if ( row == num_rows - 1 )
|
||||||
return ERROR_SUCCESS;
|
return ERROR_SUCCESS;
|
||||||
|
|
||||||
dest = tv->table->data[row];
|
for (i = row + 1; i < num_rows; i++)
|
||||||
src = tv->table->data[row + 1];
|
memcpy(tv->table->data[i - 1], tv->table->data[i], tv->row_size);
|
||||||
memmove(dest, src, (num_rows - row - 1) * tv->row_size);
|
|
||||||
return ERROR_SUCCESS;
|
return ERROR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1570,6 +1569,18 @@ static UINT msi_table_update(struct tagMSIVIEW *view, MSIRECORD *rec, UINT row)
|
||||||
return TABLE_set_row(view, new_row, rec, (1 << tv->num_cols) - 1);
|
return TABLE_set_row(view, new_row, rec, (1 << tv->num_cols) - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static UINT modify_delete_row( struct tagMSIVIEW *view, MSIRECORD *rec )
|
||||||
|
{
|
||||||
|
MSITABLEVIEW *tv = (MSITABLEVIEW *)view;
|
||||||
|
UINT row, r;
|
||||||
|
|
||||||
|
r = msi_table_find_row(tv, rec, &row);
|
||||||
|
if (r != ERROR_SUCCESS)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
return TABLE_delete_row(view, row);
|
||||||
|
}
|
||||||
|
|
||||||
static UINT TABLE_modify( struct tagMSIVIEW *view, MSIMODIFY eModifyMode,
|
static UINT TABLE_modify( struct tagMSIVIEW *view, MSIMODIFY eModifyMode,
|
||||||
MSIRECORD *rec, UINT row)
|
MSIRECORD *rec, UINT row)
|
||||||
{
|
{
|
||||||
|
@ -1580,6 +1591,9 @@ static UINT TABLE_modify( struct tagMSIVIEW *view, MSIMODIFY eModifyMode,
|
||||||
|
|
||||||
switch (eModifyMode)
|
switch (eModifyMode)
|
||||||
{
|
{
|
||||||
|
case MSIMODIFY_DELETE:
|
||||||
|
r = modify_delete_row( view, rec );
|
||||||
|
break;
|
||||||
case MSIMODIFY_VALIDATE_NEW:
|
case MSIMODIFY_VALIDATE_NEW:
|
||||||
r = table_validate_new( tv, rec );
|
r = table_validate_new( tv, rec );
|
||||||
break;
|
break;
|
||||||
|
@ -1600,7 +1614,6 @@ static UINT TABLE_modify( struct tagMSIVIEW *view, MSIMODIFY eModifyMode,
|
||||||
case MSIMODIFY_ASSIGN:
|
case MSIMODIFY_ASSIGN:
|
||||||
case MSIMODIFY_REPLACE:
|
case MSIMODIFY_REPLACE:
|
||||||
case MSIMODIFY_MERGE:
|
case MSIMODIFY_MERGE:
|
||||||
case MSIMODIFY_DELETE:
|
|
||||||
case MSIMODIFY_VALIDATE:
|
case MSIMODIFY_VALIDATE:
|
||||||
case MSIMODIFY_VALIDATE_FIELD:
|
case MSIMODIFY_VALIDATE_FIELD:
|
||||||
case MSIMODIFY_VALIDATE_DELETE:
|
case MSIMODIFY_VALIDATE_DELETE:
|
||||||
|
|
|
@ -4354,6 +4354,104 @@ static void test_stringtable(void)
|
||||||
DeleteFileA(msifile);
|
DeleteFileA(msifile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void test_viewmodify_delete(void)
|
||||||
|
{
|
||||||
|
MSIHANDLE hdb = 0, hview = 0, hrec = 0;
|
||||||
|
UINT r;
|
||||||
|
const char *query;
|
||||||
|
char buffer[0x100];
|
||||||
|
DWORD sz;
|
||||||
|
|
||||||
|
DeleteFile(msifile);
|
||||||
|
|
||||||
|
/* just MsiOpenDatabase should not create a file */
|
||||||
|
r = MsiOpenDatabase(msifile, MSIDBOPEN_CREATE, &hdb);
|
||||||
|
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
|
||||||
|
|
||||||
|
query = "CREATE TABLE `phone` ( "
|
||||||
|
"`id` INT, `name` CHAR(32), `number` CHAR(32) "
|
||||||
|
"PRIMARY KEY `id`)";
|
||||||
|
r = run_query(hdb, 0, query);
|
||||||
|
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
|
||||||
|
|
||||||
|
query = "INSERT INTO `phone` ( `id`, `name`, `number` )"
|
||||||
|
"VALUES('1', 'Alan', '5030581')";
|
||||||
|
r = run_query(hdb, 0, query);
|
||||||
|
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
|
||||||
|
|
||||||
|
query = "INSERT INTO `phone` ( `id`, `name`, `number` )"
|
||||||
|
"VALUES('2', 'Barry', '928440')";
|
||||||
|
r = run_query(hdb, 0, query);
|
||||||
|
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
|
||||||
|
|
||||||
|
query = "INSERT INTO `phone` ( `id`, `name`, `number` )"
|
||||||
|
"VALUES('3', 'Cindy', '2937550')";
|
||||||
|
r = run_query(hdb, 0, query);
|
||||||
|
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
|
||||||
|
|
||||||
|
query = "SELECT * FROM `phone` WHERE `id` <= 2";
|
||||||
|
r = MsiDatabaseOpenView(hdb, query, &hview);
|
||||||
|
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
|
||||||
|
r = MsiViewExecute(hview, 0);
|
||||||
|
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
|
||||||
|
r = MsiViewFetch(hview, &hrec);
|
||||||
|
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
|
||||||
|
|
||||||
|
/* delete 1 */
|
||||||
|
r = MsiViewModify(hview, MSIMODIFY_DELETE, hrec);
|
||||||
|
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
|
||||||
|
|
||||||
|
r = MsiCloseHandle(hrec);
|
||||||
|
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
|
||||||
|
r = MsiViewFetch(hview, &hrec);
|
||||||
|
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
|
||||||
|
|
||||||
|
/* delete 2 */
|
||||||
|
r = MsiViewModify(hview, MSIMODIFY_DELETE, hrec);
|
||||||
|
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
|
||||||
|
|
||||||
|
r = MsiCloseHandle(hrec);
|
||||||
|
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
|
||||||
|
r = MsiViewClose(hview);
|
||||||
|
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
|
||||||
|
r = MsiCloseHandle(hview);
|
||||||
|
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
|
||||||
|
|
||||||
|
query = "SELECT * FROM `phone`";
|
||||||
|
r = MsiDatabaseOpenView(hdb, query, &hview);
|
||||||
|
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
|
||||||
|
r = MsiViewExecute(hview, 0);
|
||||||
|
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
|
||||||
|
r = MsiViewFetch(hview, &hrec);
|
||||||
|
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
|
||||||
|
|
||||||
|
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, "Expected ERROR_SUCCESS, got %d\n", r);
|
||||||
|
ok(!lstrcmp(buffer, "Cindy"), "Expected Cindy, got %s\n", buffer);
|
||||||
|
|
||||||
|
sz = sizeof(buffer);
|
||||||
|
r = MsiRecordGetString(hrec, 3, buffer, &sz);
|
||||||
|
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
|
||||||
|
ok(!lstrcmp(buffer, "2937550"), "Expected 2937550, got %s\n", buffer);
|
||||||
|
|
||||||
|
r = MsiCloseHandle(hrec);
|
||||||
|
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
|
||||||
|
|
||||||
|
r = MsiViewFetch(hview, &hrec);
|
||||||
|
ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
|
||||||
|
|
||||||
|
r = MsiViewClose(hview);
|
||||||
|
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
|
||||||
|
r = MsiCloseHandle(hview);
|
||||||
|
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
|
||||||
|
r = MsiCloseHandle(hdb);
|
||||||
|
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
|
||||||
|
}
|
||||||
|
|
||||||
START_TEST(db)
|
START_TEST(db)
|
||||||
{
|
{
|
||||||
test_msidatabase();
|
test_msidatabase();
|
||||||
|
@ -4380,4 +4478,5 @@ START_TEST(db)
|
||||||
test_select_markers();
|
test_select_markers();
|
||||||
test_viewmodify_update();
|
test_viewmodify_update();
|
||||||
test_stringtable();
|
test_stringtable();
|
||||||
|
test_viewmodify_delete();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue