James Hawkins : msi: Fix deleting temporary rows, with tests.

Alexandre Julliard julliard at winehq.org
Mon Dec 24 14:21:31 CST 2007


Module: wine
Branch: master
Commit: 3c0f7ca4e6e1cd192251fda825a61dab4fa808bd
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=3c0f7ca4e6e1cd192251fda825a61dab4fa808bd

Author: James Hawkins <truiken at 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();
 }




More information about the wine-cvs mailing list