[PATCH 2/6] msi: Translate records as appropriate in SELECT_modify().

Zebediah Figura z.figura12 at gmail.com
Tue Jan 29 23:13:36 CST 2019


Signed-off-by: Zebediah Figura <z.figura12 at gmail.com>
---
 dlls/msi/select.c | 61 +++++++++++++++++++++++++++++++++++++----------
 1 file changed, 49 insertions(+), 12 deletions(-)

diff --git a/dlls/msi/select.c b/dlls/msi/select.c
index b38f339bd7..3c643f3723 100644
--- a/dlls/msi/select.c
+++ b/dlls/msi/select.c
@@ -48,6 +48,30 @@ typedef struct tagMSISELECTVIEW
     UINT           cols[1];
 } MSISELECTVIEW;
 
+static UINT translate_record( MSISELECTVIEW *sv, MSIRECORD *in, MSIRECORD **out )
+{
+    UINT r, col_count, i;
+    MSIRECORD *object;
+
+    if ((r = sv->table->ops->get_dimensions( sv->table, NULL, &col_count )))
+        return r;
+
+    if (!(object = MSI_CreateRecord( col_count )))
+        return ERROR_OUTOFMEMORY;
+
+    for (i = 0; i < sv->num_cols; i++)
+    {
+        if ((r = MSI_RecordCopyField( in, i + 1, object, sv->cols[i] )))
+        {
+            msiobj_release( &object->hdr );
+            return r;
+        }
+    }
+
+    *out = object;
+    return ERROR_SUCCESS;
+}
+
 static UINT SELECT_fetch_int( struct tagMSIVIEW *view, UINT row, UINT col, UINT *val )
 {
     MSISELECTVIEW *sv = (MSISELECTVIEW*)view;
@@ -135,7 +159,7 @@ static UINT SELECT_set_row( struct tagMSIVIEW *view, UINT row, MSIRECORD *rec, U
 static UINT SELECT_insert_row( struct tagMSIVIEW *view, MSIRECORD *record, UINT row, BOOL temporary )
 {
     MSISELECTVIEW *sv = (MSISELECTVIEW*)view;
-    UINT i, table_cols, r;
+    UINT table_cols, r;
     MSIRECORD *outrec;
 
     TRACE("%p %p\n", sv, record );
@@ -148,20 +172,12 @@ static UINT SELECT_insert_row( struct tagMSIVIEW *view, MSIRECORD *record, UINT
     if (r != ERROR_SUCCESS)
         return r;
 
-    outrec = MSI_CreateRecord( table_cols + 1 );
-
-    for (i=0; i<sv->num_cols; i++)
-    {
-        r = MSI_RecordCopyField( record, i+1, outrec, sv->cols[i] );
-        if (r != ERROR_SUCCESS)
-            goto fail;
-    }
+    if ((r = translate_record( sv, record, &outrec )))
+        return r;
 
     r = sv->table->ops->insert_row( sv->table, outrec, row, temporary );
 
-fail:
     msiobj_release( &outrec->hdr );
-
     return r;
 }
 
@@ -280,20 +296,41 @@ static UINT SELECT_modify( struct tagMSIVIEW *view, MSIMODIFY mode,
                            MSIRECORD *rec, UINT row )
 {
     MSISELECTVIEW *sv = (MSISELECTVIEW*)view;
+    MSIRECORD *table_rec;
+    UINT r;
 
     TRACE("view %p, mode %d, rec %p, row %u.\n", view, mode, rec, row);
 
     if( !sv->table )
          return ERROR_FUNCTION_FAILED;
 
+    /* Tests demonstrate that UPDATE only affects the columns selected and that
+     * others are left unchanged; however, ASSIGN overwrites unselected columns
+     * to NULL. Similarly, MERGE matches all unselected columns as NULL rather
+     * than just ignoring them. */
+
     switch (mode)
     {
     case MSIMODIFY_REFRESH:
         return msi_view_refresh_row(sv->db, view, row, rec);
     case MSIMODIFY_UPDATE:
         return msi_select_update(view, rec, row);
-    default:
+    case MSIMODIFY_INSERT:
+    case MSIMODIFY_ASSIGN:
+    case MSIMODIFY_MERGE:
+    case MSIMODIFY_INSERT_TEMPORARY:
+    case MSIMODIFY_VALIDATE_NEW:
+        if ((r = translate_record( sv, rec, &table_rec )))
+            return r;
+
+        r = sv->table->ops->modify( sv->table, mode, table_rec, row );
+        msiobj_release( &table_rec->hdr );
+        return r;
+    case MSIMODIFY_DELETE:
         return sv->table->ops->modify( sv->table, mode, rec, row );
+    default:
+        FIXME("unhandled mode %d\n", mode);
+        return ERROR_FUNCTION_FAILED;
     }
 }
 
-- 
2.20.1




More information about the wine-devel mailing list