Module: wine Branch: master Commit: 3c0f7ca4e6e1cd192251fda825a61dab4fa808bd URL: http://source.winehq.org/git/wine.git/?a=commit;h=3c0f7ca4e6e1cd192251fda825...
Author: James Hawkins truiken@gmail.com Date: Fri Dec 21 21:04:18 2007 -0600
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 844feb3..7824521 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 05a9aa9..099580d 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(); }