From 00cfd2899b7b8bf41c437170883ab0435b583eff Mon Sep 17 00:00:00 2001 From: James Hawkins Date: Tue, 12 Feb 2008 01:37:14 -0600 Subject: [PATCH] msi: Use MsiViewModify instead of building a SQL query when adding rows to the table. --- dlls/msi/database.c | 180 +++++++++++++++----------------------------- dlls/msi/tests/db.c | 24 ++---- 2 files changed, 65 insertions(+), 139 deletions(-) diff --git a/dlls/msi/database.c b/dlls/msi/database.c index 65db00b101b..a7dc2851709 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; + UINT i; - 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; -} - -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; + ERR("Unhandled column type: %c\n", types[i][0]); + msiobj_release(&(*rec)->hdr); + return ERROR_FUNCTION_FAILED; } - - 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; - } - 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 + }; + + size = lstrlenW(select) + lstrlenW(labels[0]) - 1; + query = msi_alloc(size * sizeof(WCHAR)); + if (!query) + return ERROR_OUTOFMEMORY; + + sprintfW(query, select, labels[0]); + + r = MSI_DatabaseOpenViewW(db, query, &view); + msi_free(query); + if (r != ERROR_SUCCESS) + return r; + + while (MSI_ViewFetch(view, &rec) != ERROR_NO_MORE_ITEMS) + { + r = MSI_ViewModify(view, MSIMODIFY_DELETE, rec); + if (r != ERROR_SUCCESS) + goto done; + } - 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(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); - - msi_free(data); - - r = MSI_DatabaseOpenViewW( db, insert_sql, &view ); - msi_free(insert_sql); - + 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 468f486185a..684379eaad2 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);