James Hawkins : msi: Use MsiViewModify instead of building a SQL query when adding rows to the table .

Alexandre Julliard julliard at winehq.org
Tue Feb 12 16:46:15 CST 2008


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

Author: James Hawkins <truiken at gmail.com>
Date:   Tue Feb 12 01:37:14 2008 -0600

msi: Use MsiViewModify instead of building a SQL query when adding rows to the table.

---

 dlls/msi/database.c |  176 +++++++++++++++++----------------------------------
 dlls/msi/tests/db.c |   24 ++-----
 2 files changed, 63 insertions(+), 137 deletions(-)

diff --git a/dlls/msi/database.c b/dlls/msi/database.c
index 65db00b..a7dc285 100644
--- a/dlls/msi/database.c
+++ b/dlls/msi/database.c
@@ -509,156 +509,88 @@ static UINT msi_add_table_to_db(MSIDATABASE *db, LPWSTR *columns, LPWSTR *types,
     return r;
 }
 
-static LPWSTR msi_build_insertsql_prelude(LPWSTR table)
+static UINT construct_record(DWORD num_columns, LPWSTR *types,
+                             LPWSTR *data, MSIRECORD **rec)
 {
-    LPWSTR prelude;
-    DWORD size;
-
-    static const WCHAR insert_fmt[] = {'I','N','S','E','R','T',' ','I','N','T','O',' ','`','%','s','`',' ','(',' ',0};
-
-    size = sizeof(insert_fmt) + lstrlenW(table) - 2;
-    prelude = msi_alloc(size * sizeof(WCHAR));
-    if (!prelude)
-        return NULL;
-
-    sprintfW(prelude, insert_fmt, table);
-    return prelude;
-}
+    UINT i;
 
-static LPWSTR msi_build_insertsql_columns(LPWSTR *columns_data, LPWSTR *types, DWORD num_columns)
-{
-    LPWSTR columns, p;
-    DWORD sql_size = 1, i;
-    WCHAR expanded[128];
-
-    static const WCHAR column_fmt[] =  {'`','%','s','`',',',' ',0};
-
-    columns = msi_alloc_zero(sql_size * sizeof(WCHAR));
-    if (!columns)
-        return NULL;
-
-    for (i = 0; i < num_columns; i++)
-    {
-        sprintfW(expanded, column_fmt, columns_data[i]);
-        sql_size += lstrlenW(expanded);
-
-        if (i == num_columns - 1)
-        {
-            sql_size -= 2;
-            expanded[lstrlenW(expanded) - 2] = '\0';
-        }
-
-        p = msi_realloc(columns, sql_size * sizeof(WCHAR));
-        if (!p)
-        {
-            msi_free(columns);
-            return NULL;
-        }
-        columns = p;
-
-        lstrcatW(columns, expanded);
-    }
-
-    return columns;
-}
-
-static LPWSTR msi_build_insertsql_data(LPWSTR **records, LPWSTR *types, DWORD num_columns, DWORD irec)
-{
-    LPWSTR columns, temp_columns;
-    DWORD sql_size = 1, i;
-    WCHAR expanded[128];
-
-    static const WCHAR str_fmt[] = {'\'','%','s','\'',',',' ',0};
-    static const WCHAR int_fmt[] = {'%','s',',',' ',0};
-    static const WCHAR empty[] = {'\'','\'',',',' ',0};
-
-    columns = msi_alloc_zero(sql_size * sizeof(WCHAR));
-    if (!columns)
-        return NULL;
+    *rec = MSI_CreateRecord(num_columns);
+    if (!*rec)
+        return ERROR_OUTOFMEMORY;
 
     for (i = 0; i < num_columns; i++)
     {
         switch (types[i][0])
         {
             case 'L': case 'l': case 'S': case 's':
-                sprintfW(expanded, str_fmt, records[irec][i]);
+                MSI_RecordSetStringW(*rec, i + 1, data[i]);
                 break;
             case 'I': case 'i':
-                if (*records[0][i])
-                    sprintfW(expanded, int_fmt, records[irec][i]);
-                else
-                    lstrcpyW(expanded, empty);
+                if (*data[i])
+                    MSI_RecordSetInteger(*rec, i + 1, atoiW(data[i]));
                 break;
             default:
-                HeapFree( GetProcessHeap(), 0, columns );
-                return NULL;
-        }
-
-        if (i == num_columns - 1)
-            expanded[lstrlenW(expanded) - 2] = '\0';
-
-        sql_size += lstrlenW(expanded);
-        temp_columns = msi_realloc(columns, sql_size * sizeof(WCHAR));
-        if (!temp_columns)
-        {
-            HeapFree( GetProcessHeap(), 0, columns);
-            return NULL;
+                ERR("Unhandled column type: %c\n", types[i][0]);
+                msiobj_release(&(*rec)->hdr);
+                return ERROR_FUNCTION_FAILED;
         }
-        columns = temp_columns;
-
-        lstrcatW(columns, expanded);
     }
 
-    return columns;
+    return ERROR_SUCCESS;
 }
 
 static UINT msi_add_records_to_table(MSIDATABASE *db, LPWSTR *columns, LPWSTR *types,
                                      LPWSTR *labels, LPWSTR **records,
                                      int num_columns, int num_records)
 {
+    UINT r;
+    DWORD i, size;
     MSIQUERY *view;
-    LPWSTR insert_sql;
-    DWORD size, i;
-    UINT r = ERROR_SUCCESS;
+    MSIRECORD *rec;
+    LPWSTR query;
 
-    static const WCHAR mid[] = {' ',')',' ','V','A','L','U','E','S',' ','(',' ',0};
-    static const WCHAR end[] = {' ',')',0};
+    static const WCHAR select[] = {
+        'S','E','L','E','C','T',' ','*',' ',
+        'F','R','O','M',' ','`','%','s','`',0
+    };
 
-    LPWSTR prelude = msi_build_insertsql_prelude(labels[0]);
-    LPWSTR columns_sql = msi_build_insertsql_columns(columns, types, num_columns);
-    
-    for (i = 0; i < num_records; i++)
-    {
-        LPWSTR data = msi_build_insertsql_data(records, types, num_columns, i);
+    size = lstrlenW(select) + lstrlenW(labels[0]) - 1;
+    query = msi_alloc(size * sizeof(WCHAR));
+    if (!query)
+        return ERROR_OUTOFMEMORY;
 
-        size = lstrlenW(prelude) + lstrlenW(columns_sql) + sizeof(mid) + lstrlenW(data) + sizeof(end) - 1; 
-        insert_sql = msi_alloc(size * sizeof(WCHAR));
-        if (!insert_sql)
-            return ERROR_OUTOFMEMORY;
-    
-        lstrcpyW(insert_sql, prelude);
-        lstrcatW(insert_sql, columns_sql);
-        lstrcatW(insert_sql, mid);
-        lstrcatW(insert_sql, data);
-        lstrcatW(insert_sql, end);
+    sprintfW(query, select, labels[0]);
 
-        msi_free(data);
+    r = MSI_DatabaseOpenViewW(db, query, &view);
+    msi_free(query);
+    if (r != ERROR_SUCCESS)
+        return r;
 
-        r = MSI_DatabaseOpenViewW( db, insert_sql, &view );
-        msi_free(insert_sql);
+    while (MSI_ViewFetch(view, &rec) != ERROR_NO_MORE_ITEMS)
+    {
+        r = MSI_ViewModify(view, MSIMODIFY_DELETE, rec);
+        if (r != ERROR_SUCCESS)
+            goto done;
+    }
 
+    for (i = 0; i < num_records; i++)
+    {
+        r = construct_record(num_columns, types, records[i], &rec);
         if (r != ERROR_SUCCESS)
             goto done;
 
-        r = MSI_ViewExecute(view, NULL);
-        MSI_ViewClose(view);
-        msiobj_release(&view->hdr);
+        r = MSI_ViewModify(view, MSIMODIFY_INSERT, rec);
+        if (r != ERROR_SUCCESS)
+        {
+            msiobj_release(&rec->hdr);
+            goto done;
+        }
+
+        msiobj_release(&rec->hdr);
     }
 
 done:
-    msi_free(prelude);
-    msi_free(columns_sql);
-
+    msiobj_release(&view->hdr);
     return r;
 }
 
@@ -718,9 +650,15 @@ UINT MSI_DatabaseImport(MSIDATABASE *db, LPCWSTR folder, LPCWSTR file)
         records = temp_records;
     }
 
-    r = msi_add_table_to_db( db, columns, types, labels, num_labels, num_columns );
-    if (r != ERROR_SUCCESS)
-        goto done;
+    if (!TABLE_Exists(db, labels[0]))
+    {
+        r = msi_add_table_to_db( db, columns, types, labels, num_labels, num_columns );
+        if (r != ERROR_SUCCESS)
+        {
+            r = ERROR_FUNCTION_FAILED;
+            goto done;
+        }
+    }
 
     r = msi_add_records_to_table( db, columns, types, labels, records, num_columns, num_records );
 
diff --git a/dlls/msi/tests/db.c b/dlls/msi/tests/db.c
index 468f486..684379e 100644
--- a/dlls/msi/tests/db.c
+++ b/dlls/msi/tests/db.c
@@ -1649,11 +1649,8 @@ static void test_msiimport(void)
     }
 
     r = add_table_to_db(hdb, endlines2);
-    todo_wine
-    {
-        ok(r == ERROR_FUNCTION_FAILED,
-           "Expected ERROR_FUNCTION_FAILED, got %d\n", r);
-    }
+    ok(r == ERROR_FUNCTION_FAILED,
+       "Expected ERROR_FUNCTION_FAILED, got %d\n", r);
 
     query = "SELECT * FROM `TestTable`";
     r = MsiDatabaseOpenView(hdb, query, &view);
@@ -5255,10 +5252,7 @@ static void test_quotes(void)
     write_file("import.idt", import_dat, (sizeof(import_dat) - 1) * sizeof(char));
 
     r = MsiDatabaseImportA(hdb, CURR_DIR, "import.idt");
-    todo_wine
-    {
-        ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
-    }
+    ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
 
     DeleteFileA("import.idt");
 
@@ -5275,19 +5269,13 @@ static void test_quotes(void)
     size = MAX_PATH;
     r = MsiRecordGetString(hrec, 1, buf, &size);
     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
-    todo_wine
-    {
-        ok(!lstrcmp(buf, "This is a new 'string' ok"),
-           "Expected \"This is a new 'string' ok\", got %s\n", buf);
-    }
+    ok(!lstrcmp(buf, "This is a new 'string' ok"),
+       "Expected \"This is a new 'string' ok\", got %s\n", buf);
 
     MsiCloseHandle(hrec);
 
     r = MsiViewFetch(hview, &hrec);
-    todo_wine
-    {
-        ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
-    }
+    ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
 
     MsiCloseHandle(hview);
 




More information about the wine-cvs mailing list