From 3c0f7ca4e6e1cd192251fda825a61dab4fa808bd Mon Sep 17 00:00:00 2001 From: James Hawkins Date: Fri, 21 Dec 2007 21:04:18 -0600 Subject: [PATCH] msi: Fix deleting temporary rows, with tests. --- dlls/msi/table.c | 25 +++++++++-- dlls/msi/tests/db.c | 121 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 143 insertions(+), 3 deletions(-) diff --git a/dlls/msi/table.c b/dlls/msi/table.c index 844feb31e52..7824521c413 100644 --- a/dlls/msi/table.c +++ b/dlls/msi/table.c @@ -1543,6 +1543,7 @@ static UINT TABLE_delete_row( struct tagMSIVIEW *view, UINT row ) { MSITABLEVIEW *tv = (MSITABLEVIEW*)view; UINT r, num_rows, num_cols, i; + BYTE **data; TRACE("%p %d\n", tv, row); @@ -1556,13 +1557,25 @@ static UINT TABLE_delete_row( struct tagMSIVIEW *view, UINT row ) if ( row >= num_rows ) return ERROR_FUNCTION_FAILED; - tv->table->row_count--; + if ( row < tv->table->row_count ) + { + num_rows = tv->table->row_count; + tv->table->row_count--; + data = tv->table->data; + } + else + { + num_rows = tv->table->nonpersistent_row_count; + row -= tv->table->row_count; + tv->table->nonpersistent_row_count--; + data = tv->table->nonpersistent_data; + } if ( row == num_rows - 1 ) return ERROR_SUCCESS; for (i = row + 1; i < num_rows; i++) - memcpy(tv->table->data[i - 1], tv->table->data[i], tv->row_size); + memcpy(data[i - 1], data[i], tv->row_size); return ERROR_SUCCESS; } @@ -1622,6 +1635,13 @@ static UINT TABLE_modify( struct tagMSIVIEW *view, MSIMODIFY eModifyMode, r = table_validate_new( tv, rec ); break; + case MSIMODIFY_INSERT: + r = table_validate_new( tv, rec ); + if (r != ERROR_SUCCESS) + break; + r = TABLE_insert_row( view, rec, FALSE ); + break; + case MSIMODIFY_INSERT_TEMPORARY: r = table_validate_new( tv, rec ); if (r != ERROR_SUCCESS) @@ -1634,7 +1654,6 @@ static UINT TABLE_modify( struct tagMSIVIEW *view, MSIMODIFY eModifyMode, break; case MSIMODIFY_REFRESH: - case MSIMODIFY_INSERT: case MSIMODIFY_ASSIGN: case MSIMODIFY_REPLACE: case MSIMODIFY_MERGE: diff --git a/dlls/msi/tests/db.c b/dlls/msi/tests/db.c index 05a9aa96e32..099580d1109 100644 --- a/dlls/msi/tests/db.c +++ b/dlls/msi/tests/db.c @@ -4642,6 +4642,9 @@ static void test_order(void) r = MsiViewFetch(hview, &hrec); ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); + MsiViewClose(hview); + MsiCloseHandle(hview); + query = "SELECT `A`, `D` FROM `Mesa`, `Sideboard` ORDER BY `F`"; r = MsiDatabaseOpenView(hdb, query, &hview); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); @@ -4750,8 +4753,125 @@ static void test_order(void) r = MsiViewFetch(hview, &hrec); ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); + MsiViewClose(hview); + MsiCloseHandle(hview); + MsiCloseHandle(hdb); +} + +static void test_viewmodify_delete_temporary(void) +{ + MSIHANDLE hdb, hview, hrec; + const char *query; + UINT r; + + DeleteFile(msifile); + + r = MsiOpenDatabase(msifile, MSIDBOPEN_CREATE, &hdb); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + + query = "CREATE TABLE `Table` ( `A` SHORT PRIMARY KEY `A` )"; + r = run_query(hdb, 0, query); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + + query = "SELECT * FROM `Table`"; + 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); + + hrec = MsiCreateRecord(1); + MsiRecordSetInteger(hrec, 1, 1); + + r = MsiViewModify(hview, MSIMODIFY_INSERT, hrec); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + + MsiCloseHandle(hrec); + + hrec = MsiCreateRecord(1); + MsiRecordSetInteger(hrec, 1, 2); + + r = MsiViewModify(hview, MSIMODIFY_INSERT_TEMPORARY, hrec); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + + MsiCloseHandle(hrec); + + hrec = MsiCreateRecord(1); + MsiRecordSetInteger(hrec, 1, 3); + + r = MsiViewModify(hview, MSIMODIFY_INSERT, hrec); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + + MsiCloseHandle(hrec); + + hrec = MsiCreateRecord(1); + MsiRecordSetInteger(hrec, 1, 4); + + r = MsiViewModify(hview, MSIMODIFY_INSERT_TEMPORARY, hrec); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + + MsiCloseHandle(hrec); + MsiViewClose(hview); + MsiCloseHandle(hview); + + query = "SELECT * FROM `Table` WHERE `A` = 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); + + r = MsiViewModify(hview, MSIMODIFY_DELETE, hrec); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + + MsiCloseHandle(hrec); + MsiViewClose(hview); + MsiCloseHandle(hview); + + query = "SELECT * FROM `Table` WHERE `A` = 3"; + 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 = MsiViewModify(hview, MSIMODIFY_DELETE, hrec); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + + MsiCloseHandle(hrec); + MsiViewClose(hview); + MsiCloseHandle(hview); + + query = "SELECT * FROM `Table` ORDER BY `A`"; + 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 == 1, "Expected 1, got %d\n", r); + + MsiCloseHandle(hrec); + + r = MsiViewFetch(hview, &hrec); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + + r = MsiRecordGetInteger(hrec, 1); + ok(r == 4, "Expected 4, got %d\n", r); + + MsiCloseHandle(hrec); + + r = MsiViewFetch(hview, &hrec); + ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); + + MsiViewClose(hview); MsiCloseHandle(hview); MsiCloseHandle(hdb); + DeleteFileA(msifile); } START_TEST(db) @@ -4783,4 +4903,5 @@ START_TEST(db) test_viewmodify_delete(); test_defaultdatabase(); test_order(); + test_viewmodify_delete_temporary(); } -- 2.11.4.GIT