msi: Allow more than one primary key in a table when importing a database.

This commit is contained in:
James Hawkins 2006-10-19 17:30:13 -07:00 committed by Alexandre Julliard
parent 463cec6af6
commit a66584e1a2
2 changed files with 88 additions and 12 deletions

View File

@ -409,23 +409,44 @@ static LPWSTR msi_build_createsql_columns(LPWSTR *columns_data, LPWSTR *types, D
return columns;
}
static LPWSTR msi_build_createsql_postlude(LPWSTR primary_key)
static LPWSTR msi_build_createsql_postlude(LPWSTR *primary_keys, DWORD num_keys)
{
LPWSTR postlude;
DWORD size;
LPWSTR postlude, keys, ptr;
DWORD size, key_size, i;
static const WCHAR postlude_fmt[] = {'P','R','I','M','A','R','Y',' ','K','E','Y',' ','`','%','s','`',')',' ','H','O','L','D',0};
static const WCHAR key_fmt[] = {'`','%','s','`',',',' ',0};
static const WCHAR postlude_fmt[] = {'P','R','I','M','A','R','Y',' ','K','E','Y',' ','%','s',')',' ','H','O','L','D',0};
size = sizeof(postlude_fmt) + lstrlenW(primary_key) - 2;
postlude = msi_alloc(size * sizeof(WCHAR));
if (!postlude)
for (i = 0, size = 1; i < num_keys; i++)
size += lstrlenW(key_fmt) + lstrlenW(primary_keys[i]) - 2;
keys = msi_alloc(size * sizeof(WCHAR));
if (!keys)
return NULL;
sprintfW(postlude, postlude_fmt, primary_key);
for (i = 0, ptr = keys; i < num_keys; i++)
{
key_size = lstrlenW(key_fmt) + lstrlenW(primary_keys[i]) -2;
sprintfW(ptr, key_fmt, primary_keys[i]);
ptr += key_size;
}
/* remove final ', ' */
*(ptr - 2) = '\0';
size = lstrlenW(postlude_fmt) + size - 1;
postlude = msi_alloc(size * sizeof(WCHAR));
if (!postlude)
goto done;
sprintfW(postlude, postlude_fmt, keys);
done:
msi_free(keys);
return postlude;
}
static UINT msi_add_table_to_db(MSIDATABASE *db, LPWSTR *columns, LPWSTR *types, LPWSTR *labels, DWORD num_columns)
static UINT msi_add_table_to_db(MSIDATABASE *db, LPWSTR *columns, LPWSTR *types, LPWSTR *labels, DWORD num_labels, DWORD num_columns)
{
UINT r;
DWORD size;
@ -435,7 +456,7 @@ static UINT msi_add_table_to_db(MSIDATABASE *db, LPWSTR *columns, LPWSTR *types,
prelude = msi_build_createsql_prelude(labels[0]);
columns_sql = msi_build_createsql_columns(columns, types, num_columns);
postlude = msi_build_createsql_postlude(labels[1]);
postlude = msi_build_createsql_postlude(labels + 1, num_labels - 1); /* skip over table name */
if (!prelude || !columns_sql || !postlude)
return ERROR_OUTOFMEMORY;
@ -614,6 +635,7 @@ UINT MSI_DatabaseImport(MSIDATABASE *db, LPCWSTR folder, LPCWSTR file)
{
UINT r;
DWORD len, i;
DWORD num_labels;
DWORD num_columns, num_records = 0;
LPWSTR *columns, *types, *labels;
LPWSTR path, ptr, data;
@ -640,7 +662,7 @@ UINT MSI_DatabaseImport(MSIDATABASE *db, LPCWSTR folder, LPCWSTR file)
ptr = data;
msi_parse_line( &ptr, &columns, &num_columns );
msi_parse_line( &ptr, &types, NULL );
msi_parse_line( &ptr, &labels, NULL );
msi_parse_line( &ptr, &labels, &num_labels );
records = msi_alloc(sizeof(LPWSTR *));
if (!records)
@ -657,7 +679,7 @@ UINT MSI_DatabaseImport(MSIDATABASE *db, LPCWSTR folder, LPCWSTR file)
return ERROR_OUTOFMEMORY;
}
r = msi_add_table_to_db( db, columns, types, labels, num_columns );
r = msi_add_table_to_db( db, columns, types, labels, num_labels, num_columns );
if (r != ERROR_SUCCESS)
goto done;

View File

@ -1365,6 +1365,12 @@ static const CHAR test_data[] = "FirstPrimaryColumn\tSecondPrimaryColumn\tShortI
"TestTable\tFirstPrimaryColumn\n"
"stringage\t5\t2\t\t2147483640\t-2147483640\tanother string\tlocalizable\tduh\n";
static const CHAR two_primary[] = "PrimaryOne\tPrimaryTwo\n"
"s255\ts255\n"
"TwoPrimary\tPrimaryOne\tPrimaryTwo\n"
"papaya\tleaf\n"
"papaya\tflower\n";
static void write_file(const CHAR *filename, const char *data, int data_size)
{
DWORD size;
@ -1402,6 +1408,9 @@ static void test_msiimport(void)
r = add_table_to_db(hdb, test_data);
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
r = add_table_to_db(hdb, two_primary);
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
query = "SELECT * FROM `TestTable`";
r = MsiDatabaseOpenView(hdb, query, &view);
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
@ -1464,6 +1473,51 @@ static void test_msiimport(void)
ok(i == -2147483640, "Expected -2147483640, got %d\n", i);
MsiCloseHandle(rec);
MsiCloseHandle(view);
query = "SELECT * FROM `TwoPrimary`";
r = MsiDatabaseOpenView(hdb, query, &view);
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
r = MsiViewGetColumnInfo(view, MSICOLINFO_NAMES, &rec);
count = MsiRecordGetFieldCount(rec);
ok(count == 2, "Expected 2, got %d\n", count);
ok(check_record(rec, 1, "PrimaryOne"), "Expected PrimaryOne\n");
ok(check_record(rec, 2, "PrimaryTwo"), "Expected PrimaryTwo\n");
MsiCloseHandle(rec);
r = MsiViewGetColumnInfo(view, MSICOLINFO_TYPES, &rec);
count = MsiRecordGetFieldCount(rec);
ok(count == 2, "Expected 2, got %d\n", count);
ok(check_record(rec, 1, "s255"), "Expected s255\n");
ok(check_record(rec, 2, "s255"), "Expected s255\n");
r = MsiViewExecute(view, 0);
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
r = MsiViewFetch(view, &rec);
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
ok(check_record(rec, 1, "papaya"), "Expected 'papaya'\n");
ok(check_record(rec, 2, "leaf"), "Expected 'leaf'\n");
MsiCloseHandle(rec);
r = MsiViewFetch(view, &rec);
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
ok(check_record(rec, 1, "papaya"), "Expected 'papaya'\n");
ok(check_record(rec, 2, "flower"), "Expected 'flower'\n");
MsiCloseHandle(rec);
r = MsiViewFetch(view, &rec);
ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
r = MsiViewClose(view);
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
MsiCloseHandle(view);
MsiCloseHandle(hdb);
DeleteFileA(msifile);