Commit 35a6782d authored by James Hawkins's avatar James Hawkins Committed by Alexandre Julliard

msi: Test and implement the MSIMODIFY_DELETE command.

parent 341d1fa7
...@@ -567,6 +567,7 @@ UINT WINAPI MsiViewGetColumnInfo(MSIHANDLE hView, MSICOLINFO info, MSIHANDLE *hR ...@@ -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 ) ...@@ -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 ...@@ -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 ) ...@@ -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) ...@@ -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, ...@@ -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, ...@@ -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) ...@@ -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) ...@@ -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();
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment