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