Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/msi/tests/db.c | 55 ++++++++++++++++++++++++++++++++++++--------- 1 file changed, 45 insertions(+), 10 deletions(-)
diff --git a/dlls/msi/tests/db.c b/dlls/msi/tests/db.c index e8ae8d21d3..bcde840bd8 100644 --- a/dlls/msi/tests/db.c +++ b/dlls/msi/tests/db.c @@ -3620,28 +3620,63 @@ static void test_join(void) ok( r == ERROR_SUCCESS, "failed to fetch view: %d\n", r ); check_record(hrec, 2, "alveolar", "procerus");
+ r = MsiRecordSetStringA( hrec, 1, "fascia" ); + ok( r == ERROR_SUCCESS, "failed to set string: %d\n", r ); + r = MsiRecordSetStringA( hrec, 2, "pterygoid" ); + ok( r == ERROR_SUCCESS, "failed to set string: %d\n", r ); + + r = MsiViewModify(hview, MSIMODIFY_REFRESH, hrec); + ok( r == ERROR_SUCCESS, "failed to refresh row: %d\n", r ); + check_record(hrec, 2, "alveolar", "procerus"); + r = MsiRecordSetStringA( hrec, 1, "epicranius" ); ok( r == ERROR_SUCCESS, "failed to set string: %d\n", r );
r = MsiViewModify(hview, MSIMODIFY_UPDATE, hrec); ok( r == ERROR_SUCCESS, "failed to update row: %d\n", r );
- /* try another valid operation for joins */ - r = MsiViewModify(hview, MSIMODIFY_REFRESH, hrec); - ok( r == ERROR_SUCCESS, "failed to refresh row: %d\n", r ); - check_record(hrec, 2, "epicranius", "procerus"); - - /* try an invalid operation for joins */ - r = MsiViewModify(hview, MSIMODIFY_DELETE, hrec); - ok( r == ERROR_FUNCTION_FAILED, "unexpected result: %d\n", r ); - + /* primary key cannot be updated */ r = MsiRecordSetStringA( hrec, 2, "epicranius" ); ok( r == ERROR_SUCCESS, "failed to set string: %d\n", r );
- /* primary key cannot be updated */ r = MsiViewModify(hview, MSIMODIFY_UPDATE, hrec); ok( r == ERROR_FUNCTION_FAILED, "failed to update row: %d\n", r );
+ /* all other operations are invalid for joins */ + r = MsiViewModify(hview, MSIMODIFY_SEEK, hrec); + ok( r == ERROR_FUNCTION_FAILED, "unexpected result: %d\n", r ); + + r = MsiViewModify(hview, MSIMODIFY_ASSIGN, hrec); + ok( r == ERROR_FUNCTION_FAILED, "unexpected result: %d\n", r ); + + r = MsiViewModify(hview, MSIMODIFY_REPLACE, hrec); + ok( r == ERROR_FUNCTION_FAILED, "unexpected result: %d\n", r ); + + r = MsiViewModify(hview, MSIMODIFY_MERGE, hrec); + ok( r == ERROR_FUNCTION_FAILED, "unexpected result: %d\n", r ); + + r = MsiViewModify(hview, MSIMODIFY_DELETE, hrec); + ok( r == ERROR_FUNCTION_FAILED, "unexpected result: %d\n", r ); + + r = MsiViewModify(hview, MSIMODIFY_VALIDATE, hrec); + ok( r == ERROR_FUNCTION_FAILED, "unexpected result: %d\n", r ); + + r = MsiViewModify(hview, MSIMODIFY_VALIDATE_DELETE, hrec); + ok( r == ERROR_FUNCTION_FAILED, "unexpected result: %d\n", r ); + + MsiRecordSetStringA(hrec, 2, "epicranius"); + r = MsiViewModify(hview, MSIMODIFY_INSERT, hrec); + ok( r == ERROR_FUNCTION_FAILED, "unexpected result: %d\n", r ); + + r = MsiViewModify(hview, MSIMODIFY_INSERT_TEMPORARY, hrec); + ok( r == ERROR_FUNCTION_FAILED, "unexpected result: %d\n", r ); + + r = MsiViewModify(hview, MSIMODIFY_VALIDATE_NEW, hrec); + ok( r == ERROR_FUNCTION_FAILED, "unexpected result: %d\n", r ); + + r = MsiViewModify(hview, MSIMODIFY_VALIDATE_FIELD, hrec); + ok( r == ERROR_FUNCTION_FAILED, "unexpected result: %d\n", r ); + MsiCloseHandle(hrec); MsiViewClose(hview); MsiCloseHandle(hview);
Signed-off-by: Zebediah Figura z.figura12@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; } }
Signed-off-by: Hans Leidekker hans@codeweavers.com
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/msi/tests/db.c | 172 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 160 insertions(+), 12 deletions(-)
diff --git a/dlls/msi/tests/db.c b/dlls/msi/tests/db.c index bcde840bd8..e59846ffad 100644 --- a/dlls/msi/tests/db.c +++ b/dlls/msi/tests/db.c @@ -5176,12 +5176,7 @@ static void test_viewmodify_assign(void) ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n"); r = MsiViewFetch(hview, &hrec); ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n"); - - r = MsiRecordGetInteger(hrec, 1); - ok(r == 1, "Expected 1, got %d\n", r); - r = MsiRecordGetInteger(hrec, 2); - ok(r == 2, "Expected 2, got %d\n", r); - + check_record(hrec, 2, "1", "2"); r = MsiCloseHandle(hrec); ok(r == ERROR_SUCCESS, "failed to close record\n");
@@ -5226,12 +5221,7 @@ static void test_viewmodify_assign(void) ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n"); r = MsiViewFetch(hview, &hrec); ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n"); - - r = MsiRecordGetInteger(hrec, 1); - ok(r == 1, "Expected 1, got %d\n", r); - r = MsiRecordGetInteger(hrec, 2); - ok(r == 4, "Expected 4, got %d\n", r); - + check_record(hrec, 2, "1", "4"); r = MsiCloseHandle(hrec); ok(r == ERROR_SUCCESS, "failed to close record\n");
@@ -5243,6 +5233,164 @@ static void test_viewmodify_assign(void) r = MsiCloseHandle(hview); ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
+ r = run_query(hdb, 0, "CREATE TABLE `table2` (`A` INT, `B` INT, `C` INT, `D` INT PRIMARY KEY `A`,`B`)"); + ok(!r, "got %u\n", r); + + r = MsiDatabaseOpenViewA(hdb, "SELECT * FROM `table2`", &hview); + ok(!r, "got %u\n", r); + r = MsiViewExecute(hview, 0); + ok(!r, "got %u\n", r); + + hrec = MsiCreateRecord(4); + MsiRecordSetInteger(hrec, 1, 1); + MsiRecordSetInteger(hrec, 2, 2); + MsiRecordSetInteger(hrec, 3, 3); + MsiRecordSetInteger(hrec, 4, 4); + r = MsiViewModify(hview, MSIMODIFY_ASSIGN, hrec); + ok(!r, "got %u\n", r); + MsiCloseHandle(hrec); + + MsiCloseHandle(hview); + + r = MsiDatabaseOpenViewA(hdb, "SELECT * FROM `table2`", &hview); + ok(!r, "got %u\n", r); + r = MsiViewExecute(hview, 0); + ok(!r, "got %u\n", r); + + r = MsiViewFetch(hview, &hrec); + ok(!r, "got %u\n", r); + check_record(hrec, 4, "1", "2", "3", "4"); + MsiCloseHandle(hrec); + + r = MsiViewFetch(hview, &hrec); + ok(r == ERROR_NO_MORE_ITEMS, "got %u\n", r); + MsiCloseHandle(hview); + + r = MsiDatabaseOpenViewA(hdb, "SELECT * FROM `table2`", &hview); + ok(!r, "got %u\n", r); + r = MsiViewExecute(hview, 0); + ok(!r, "got %u\n", r); + + hrec = MsiCreateRecord(4); + MsiRecordSetInteger(hrec, 1, 1); + MsiRecordSetInteger(hrec, 2, 4); + MsiRecordSetInteger(hrec, 3, 3); + MsiRecordSetInteger(hrec, 4, 3); + r = MsiViewModify(hview, MSIMODIFY_ASSIGN, hrec); + ok(!r, "got %u\n", r); + MsiCloseHandle(hrec); + + MsiCloseHandle(hview); + + r = MsiDatabaseOpenViewA(hdb, "SELECT * FROM `table2`", &hview); + ok(!r, "got %u\n", r); + r = MsiViewExecute(hview, 0); + ok(!r, "got %u\n", r); + + r = MsiViewFetch(hview, &hrec); + ok(!r, "got %u\n", r); + check_record(hrec, 4, "1", "2", "3", "4"); + MsiCloseHandle(hrec); + + r = MsiViewFetch(hview, &hrec); + ok(!r, "got %u\n", r); + check_record(hrec, 4, "1", "4", "3", "3"); + MsiCloseHandle(hrec); + + r = MsiViewFetch(hview, &hrec); + ok(r == ERROR_NO_MORE_ITEMS, "got %u\n", r); + MsiCloseHandle(hview); + + r = MsiDatabaseOpenViewA(hdb, "SELECT `B`, `C` FROM `table2`", &hview); + ok(!r, "got %u\n", r); + r = MsiViewExecute(hview, 0); + ok(!r, "got %u\n", r); + + hrec = MsiCreateRecord(2); + MsiRecordSetInteger(hrec, 1, 2); + MsiRecordSetInteger(hrec, 2, 4); + r = MsiViewModify(hview, MSIMODIFY_ASSIGN, hrec); + ok(!r, "got %u\n", r); + MsiRecordSetInteger(hrec, 1, 3); + r = MsiViewModify(hview, MSIMODIFY_ASSIGN, hrec); + ok(!r, "got %u\n", r); + MsiCloseHandle(hrec); + + MsiCloseHandle(hview); + + r = MsiDatabaseOpenViewA(hdb, "SELECT * FROM `table2` ORDER BY `A`", &hview); + ok(!r, "got %u\n", r); + r = MsiViewExecute(hview, 0); + ok(!r, "got %u\n", r); + + r = MsiViewFetch(hview, &hrec); + ok(!r, "got %u\n", r); + check_record(hrec, 4, "", "2", "4", ""); + MsiCloseHandle(hrec); + + r = MsiViewFetch(hview, &hrec); + ok(!r, "got %u\n", r); + check_record(hrec, 4, "", "3", "4", ""); + MsiCloseHandle(hrec); + + r = MsiViewFetch(hview, &hrec); + ok(!r, "got %u\n", r); + check_record(hrec, 4, "1", "2", "3", "4"); + MsiCloseHandle(hrec); + + r = MsiViewFetch(hview, &hrec); + ok(!r, "got %u\n", r); + check_record(hrec, 4, "1", "4", "3", "3"); + MsiCloseHandle(hrec); + + r = MsiViewFetch(hview, &hrec); + ok(r == ERROR_NO_MORE_ITEMS, "got %u\n", r); + MsiCloseHandle(hview); + + r = MsiDatabaseOpenViewA(hdb, "SELECT `A`, `B`, `C` FROM `table2`", &hview); + ok(!r, "got %u\n", r); + r = MsiViewExecute(hview, 0); + ok(!r, "got %u\n", r); + + hrec = MsiCreateRecord(3); + MsiRecordSetInteger(hrec, 1, 1); + MsiRecordSetInteger(hrec, 2, 2); + MsiRecordSetInteger(hrec, 3, 5); + r = MsiViewModify(hview, MSIMODIFY_ASSIGN, hrec); + ok(!r, "got %u\n", r); + MsiCloseHandle(hrec); + + MsiCloseHandle(hview); + + r = MsiDatabaseOpenViewA(hdb, "SELECT * FROM `table2` ORDER BY `A`", &hview); + ok(!r, "got %u\n", r); + r = MsiViewExecute(hview, 0); + ok(!r, "got %u\n", r); + + r = MsiViewFetch(hview, &hrec); + ok(!r, "got %u\n", r); + check_record(hrec, 4, "", "2", "4", ""); + MsiCloseHandle(hrec); + + r = MsiViewFetch(hview, &hrec); + ok(!r, "got %u\n", r); + check_record(hrec, 4, "", "3", "4", ""); + MsiCloseHandle(hrec); + + r = MsiViewFetch(hview, &hrec); + ok(!r, "got %u\n", r); + check_record(hrec, 4, "1", "2", "5", ""); + MsiCloseHandle(hrec); + + r = MsiViewFetch(hview, &hrec); + ok(!r, "got %u\n", r); + check_record(hrec, 4, "1", "4", "3", "3"); + MsiCloseHandle(hrec); + + r = MsiViewFetch(hview, &hrec); + ok(r == ERROR_NO_MORE_ITEMS, "got %u\n", r); + MsiCloseHandle(hview); + /* close database */ r = MsiCloseHandle( hdb ); ok(r == ERROR_SUCCESS, "MsiOpenDatabase close failed\n");
Signed-off-by: Hans Leidekker hans@codeweavers.com
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/msi/tests/db.c | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+)
diff --git a/dlls/msi/tests/db.c b/dlls/msi/tests/db.c index e59846ffad..f219b9a9a3 100644 --- a/dlls/msi/tests/db.c +++ b/dlls/msi/tests/db.c @@ -6750,6 +6750,17 @@ static void test_viewmodify_refresh(void)
r = MsiViewFetch(hview, &hrec); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + check_record(hrec, 2, "hi", "1"); + + MsiRecordSetInteger(hrec, 2, 5); + r = MsiViewModify(hview, MSIMODIFY_REFRESH, hrec); + ok(!r, "got %u\n", r); + check_record(hrec, 2, "hi", "1"); + + MsiRecordSetStringA(hrec, 1, "foo"); + r = MsiViewModify(hview, MSIMODIFY_REFRESH, hrec); + ok(!r, "got %u\n", r); + check_record(hrec, 2, "hi", "1");
query = "UPDATE `Table` SET `B` = 2 WHERE `A` = 'hi'"; r = run_query(hdb, 0, query); @@ -6758,6 +6769,14 @@ static void test_viewmodify_refresh(void) r = MsiViewModify(hview, MSIMODIFY_REFRESH, hrec); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); check_record(hrec, 2, "hi", "2"); + + r = run_query(hdb, 0, "UPDATE `Table` SET `B` = NULL WHERE `A` = 'hi'"); + ok(!r, "got %u\n", r); + + r = MsiViewModify(hview, MSIMODIFY_REFRESH, hrec); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + check_record(hrec, 2, "hi", ""); + MsiCloseHandle(hrec);
MsiViewClose(hview); @@ -6791,6 +6810,24 @@ static void test_viewmodify_refresh(void)
MsiViewClose(hview); MsiCloseHandle(hview); + + r = MsiDatabaseOpenViewA(hdb, "SELECT `B` FROM `Table` WHERE `A` = 'hello'", &hview); + ok(!r, "got %u\n", r); + r = MsiViewExecute(hview, 0); + ok(!r, "got %u\n", r); + + r = MsiViewFetch(hview, &hrec); + ok(!r, "got %u\n", r); + check_record(hrec, 1, "2"); + + MsiRecordSetInteger(hrec, 1, 8); + r = MsiViewModify(hview, MSIMODIFY_REFRESH, hrec); + ok(!r, "got %u\n", r); + check_record(hrec, 1, "2"); + + MsiCloseHandle(hrec); + MsiCloseHandle(hview); + MsiCloseHandle(hdb); DeleteFileA(msifile); }
Signed-off-by: Hans Leidekker hans@codeweavers.com
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/msi/tests/db.c | 198 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 198 insertions(+)
diff --git a/dlls/msi/tests/db.c b/dlls/msi/tests/db.c index f219b9a9a3..2ff9fe2a5e 100644 --- a/dlls/msi/tests/db.c +++ b/dlls/msi/tests/db.c @@ -8670,6 +8670,203 @@ static void test_primary_keys(void) DeleteFileA(msifile); }
+static void test_viewmodify_merge(void) +{ + MSIHANDLE view, rec, db = create_db(); + UINT r; + + r = run_query(db, 0, "CREATE TABLE `T` (`A` SHORT, `B` SHORT PRIMARY KEY `A`)"); + ok(!r, "got %u\n", r); + r = run_query(db, 0, "INSERT INTO `T` (`A`, `B`) VALUES (1, 2)"); + ok(!r, "got %u\n", r); + + r = MsiDatabaseOpenViewA(db, "SELECT * FROM `T`", &view); + ok(!r, "got %u\n", r); + r = MsiViewExecute(view, 0); + ok(!r, "got %u\n", r); + + rec = MsiCreateRecord(2); + MsiRecordSetInteger(rec, 1, 1); + MsiRecordSetInteger(rec, 2, 2); + r = MsiViewModify(view, MSIMODIFY_MERGE, rec); + ok(!r, "got %u\n", r); + + MsiCloseHandle(rec); + MsiCloseHandle(view); + + r = MsiDatabaseOpenViewA(db, "SELECT * FROM `T`", &view); + ok(!r, "got %u\n", r); + r = MsiViewExecute(view, 0); + ok(!r, "got %u\n", r); + + r = MsiViewFetch(view, &rec); + ok(!r, "got %u\n", r); + check_record(rec, 2, "1", "2"); + MsiCloseHandle(rec); + + r = MsiViewFetch(view, &rec); + ok(r == ERROR_NO_MORE_ITEMS, "got %u\n", r); + MsiCloseHandle(view); + + r = MsiDatabaseOpenViewA(db, "SELECT * FROM `T`", &view); + ok(!r, "got %u\n", r); + r = MsiViewExecute(view, 0); + ok(!r, "got %u\n", r); + + rec = MsiCreateRecord(2); + MsiRecordSetInteger(rec, 1, 1); + MsiRecordSetInteger(rec, 2, 3); + r = MsiViewModify(view, MSIMODIFY_MERGE, rec); +todo_wine + ok(r == ERROR_FUNCTION_FAILED, "got %u\n", r); + + MsiRecordSetInteger(rec, 1, 2); + r = MsiViewModify(view, MSIMODIFY_MERGE, rec); + ok(!r, "got %u\n", r); + + MsiCloseHandle(rec); + MsiCloseHandle(view); + + r = MsiDatabaseOpenViewA(db, "SELECT * FROM `T`", &view); + ok(!r, "got %u\n", r); + r = MsiViewExecute(view, 0); + ok(!r, "got %u\n", r); + + r = MsiViewFetch(view, &rec); + ok(!r, "got %u\n", r); + check_record(rec, 2, "1", "2"); + MsiCloseHandle(rec); + + r = MsiViewFetch(view, &rec); + ok(!r, "got %u\n", r); + check_record(rec, 2, "2", "3"); + MsiCloseHandle(rec); + + r = MsiViewFetch(view, &rec); + ok(r == ERROR_NO_MORE_ITEMS, "got %u\n", r); + MsiCloseHandle(view); + + r = run_query(db, 0, "CREATE TABLE `U` (`A` SHORT, `B` SHORT, `C` SHORT, `D` SHORT PRIMARY KEY `A`, `B`)"); + ok(!r, "got %u\n", r); + r = run_query(db, 0, "INSERT INTO `U` (`A`, `B`, `C`, `D`) VALUES (1, 2, 3, 4)"); + ok(!r, "got %u\n", r); + + r = MsiDatabaseOpenViewA(db, "SELECT * FROM `U`", &view); + ok(!r, "got %u\n", r); + r = MsiViewExecute(view, 0); + ok(!r, "got %u\n", r); + + rec = MsiCreateRecord(4); + MsiRecordSetInteger(rec, 1, 1); + MsiRecordSetInteger(rec, 2, 2); + MsiRecordSetInteger(rec, 3, 3); + MsiRecordSetInteger(rec, 4, 4); + r = MsiViewModify(view, MSIMODIFY_MERGE, rec); + ok(!r, "got %u\n", r); + + MsiRecordSetInteger(rec, 3, 4); + r = MsiViewModify(view, MSIMODIFY_MERGE, rec); +todo_wine + ok(r == ERROR_FUNCTION_FAILED, "got %u\n", r); + + MsiRecordSetInteger(rec, 2, 4); + r = MsiViewModify(view, MSIMODIFY_MERGE, rec); + ok(!r, "got %u\n", r); + + MsiCloseHandle(rec); + MsiCloseHandle(view); + + r = MsiDatabaseOpenViewA(db, "SELECT * FROM `U`", &view); + ok(!r, "got %u\n", r); + r = MsiViewExecute(view, 0); + ok(!r, "got %u\n", r); + + r = MsiViewFetch(view, &rec); + ok(!r, "got %u\n", r); + check_record(rec, 4, "1", "2", "3", "4"); + MsiCloseHandle(rec); + + r = MsiViewFetch(view, &rec); + ok(!r, "got %u\n", r); + check_record(rec, 4, "1", "4", "4", "4"); + MsiCloseHandle(rec); + + r = MsiViewFetch(view, &rec); + ok(r == ERROR_NO_MORE_ITEMS, "got %u\n", r); + MsiCloseHandle(view); + + r = MsiDatabaseOpenViewA(db, "SELECT `A`,`C` FROM `U`", &view); + ok(!r, "got %u\n", r); + r = MsiViewExecute(view, 0); + ok(!r, "got %u\n", r); + + rec = MsiCreateRecord(2); + MsiRecordSetInteger(rec, 1, 1); + MsiRecordSetInteger(rec, 2, 2); + r = MsiViewModify(view, MSIMODIFY_MERGE, rec); + ok(!r, "got %u\n", r); + + r = MsiViewModify(view, MSIMODIFY_MERGE, rec); + ok(!r, "got %u\n", r); + + MsiRecordSetInteger(rec, 2, 3); + r = MsiViewModify(view, MSIMODIFY_MERGE, rec); +todo_wine + ok(r == ERROR_FUNCTION_FAILED, "got %u\n", r); + + MsiCloseHandle(rec); + MsiCloseHandle(view); + + r = MsiDatabaseOpenViewA(db, "SELECT * FROM `U` ORDER BY `B`", &view); + ok(!r, "got %u\n", r); + r = MsiViewExecute(view, 0); + ok(!r, "got %u\n", r); + + r = MsiViewFetch(view, &rec); + ok(!r, "got %u\n", r); + check_record(rec, 4, "1", "", "2", ""); + MsiCloseHandle(rec); + + r = MsiViewFetch(view, &rec); + ok(!r, "got %u\n", r); + check_record(rec, 4, "1", "2", "3", "4"); + MsiCloseHandle(rec); + + r = MsiViewFetch(view, &rec); + ok(!r, "got %u\n", r); + check_record(rec, 4, "1", "4", "4", "4"); + MsiCloseHandle(rec); + + r = MsiViewFetch(view, &rec); + ok(r == ERROR_NO_MORE_ITEMS, "got %u\n", r); + MsiCloseHandle(view); + + r = MsiDatabaseOpenViewA(db, "SELECT `A`,`B`,`C` FROM `U`", &view); + ok(!r, "got %u\n", r); + r = MsiViewExecute(view, 0); + ok(!r, "got %u\n", r); + + rec = MsiCreateRecord(3); + MsiRecordSetInteger(rec, 1, 1); + MsiRecordSetInteger(rec, 2, 2); + MsiRecordSetInteger(rec, 3, 3); + r = MsiViewModify(view, MSIMODIFY_MERGE, rec); +todo_wine + ok(r == ERROR_FUNCTION_FAILED, "got %u\n", r); + + MsiRecordSetInteger(rec, 1, 1); + MsiRecordSetInteger(rec, 2, MSI_NULL_INTEGER); + MsiRecordSetInteger(rec, 3, 2); + r = MsiViewModify(view, MSIMODIFY_MERGE, rec); + ok(!r, "got %u\n", r); + + MsiCloseHandle(rec); + MsiCloseHandle(view); + + MsiCloseHandle(db); + DeleteFileA(msifile); +} + START_TEST(db) { test_msidatabase(); @@ -8726,4 +8923,5 @@ START_TEST(db) test_embedded_nulls(); test_select_column_names(); test_primary_keys(); + test_viewmodify_merge(); }
Signed-off-by: Hans Leidekker hans@codeweavers.com
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/msi/tests/db.c | 165 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 165 insertions(+)
diff --git a/dlls/msi/tests/db.c b/dlls/msi/tests/db.c index 2ff9fe2a5e..0382e5454f 100644 --- a/dlls/msi/tests/db.c +++ b/dlls/msi/tests/db.c @@ -8867,6 +8867,170 @@ todo_wine DeleteFileA(msifile); }
+static void test_viewmodify_insert(void) +{ + MSIHANDLE view, rec, db = create_db(); + UINT r; + + r = run_query(db, 0, "CREATE TABLE `T` (`A` SHORT, `B` SHORT PRIMARY KEY `A`)"); + ok(!r, "got %u\n", r); + + r = MsiDatabaseOpenViewA(db, "SELECT * FROM `T`", &view); + ok(!r, "got %u\n", r); + r = MsiViewExecute(view, 0); + ok(!r, "got %u\n", r); + + rec = MsiCreateRecord(2); + MsiRecordSetInteger(rec, 1, 1); + MsiRecordSetInteger(rec, 2, 2); + r = MsiViewModify(view, MSIMODIFY_INSERT, rec); + ok(!r, "got %u\n", r); + + MsiCloseHandle(rec); + MsiCloseHandle(view); + + r = MsiDatabaseOpenViewA(db, "SELECT * FROM `T`", &view); + ok(!r, "got %u\n", r); + r = MsiViewExecute(view, 0); + ok(!r, "got %u\n", r); + + r = MsiViewFetch(view, &rec); + ok(!r, "got %u\n", r); + check_record(rec, 2, "1", "2"); + MsiCloseHandle(rec); + + r = MsiViewFetch(view, &rec); + ok(r == ERROR_NO_MORE_ITEMS, "got %u\n", r); + MsiCloseHandle(view); + + r = MsiDatabaseOpenViewA(db, "SELECT * FROM `T`", &view); + ok(!r, "got %u\n", r); + r = MsiViewExecute(view, 0); + ok(!r, "got %u\n", r); + + rec = MsiCreateRecord(2); + MsiRecordSetInteger(rec, 1, 1); + MsiRecordSetInteger(rec, 2, 2); + r = MsiViewModify(view, MSIMODIFY_INSERT, rec); + ok(r == ERROR_FUNCTION_FAILED, "got %u\n", r); + + MsiRecordSetInteger(rec, 2, 3); + r = MsiViewModify(view, MSIMODIFY_INSERT, rec); + ok(r == ERROR_FUNCTION_FAILED, "got %u\n", r); + + MsiRecordSetInteger(rec, 1, 3); + r = MsiViewModify(view, MSIMODIFY_INSERT, rec); + ok(!r, "got %u\n", r); + + MsiCloseHandle(rec); + MsiCloseHandle(view); + + r = MsiDatabaseOpenViewA(db, "SELECT * FROM `T`", &view); + ok(!r, "got %u\n", r); + r = MsiViewExecute(view, 0); + ok(!r, "got %u\n", r); + + r = MsiViewFetch(view, &rec); + ok(!r, "got %u\n", r); + check_record(rec, 2, "1", "2"); + MsiCloseHandle(rec); + + r = MsiViewFetch(view, &rec); + ok(!r, "got %u\n", r); + check_record(rec, 2, "3", "3"); + MsiCloseHandle(rec); + + r = MsiViewFetch(view, &rec); + ok(r == ERROR_NO_MORE_ITEMS, "got %u\n", r); + MsiCloseHandle(view); + + r = run_query(db, 0, "CREATE TABLE `U` (`A` SHORT, `B` SHORT, `C` SHORT, `D` SHORT PRIMARY KEY `A`, `B`)"); + ok(!r, "got %u\n", r); + + r = MsiDatabaseOpenViewA(db, "SELECT * FROM `U`", &view); + ok(!r, "got %u\n", r); + r = MsiViewExecute(view, 0); + ok(!r, "got %u\n", r); + + rec = MsiCreateRecord(4); + MsiRecordSetInteger(rec, 1, 1); + MsiRecordSetInteger(rec, 2, 2); + MsiRecordSetInteger(rec, 3, 3); + MsiRecordSetInteger(rec, 4, 4); + r = MsiViewModify(view, MSIMODIFY_INSERT, rec); + ok(!r, "got %u\n", r); + + MsiRecordSetInteger(rec, 2, 4); + r = MsiViewModify(view, MSIMODIFY_INSERT, rec); + ok(!r, "got %u\n", r); + + MsiCloseHandle(rec); + MsiCloseHandle(view); + + r = MsiDatabaseOpenViewA(db, "SELECT * FROM `U`", &view); + ok(!r, "got %u\n", r); + r = MsiViewExecute(view, 0); + ok(!r, "got %u\n", r); + + r = MsiViewFetch(view, &rec); + ok(!r, "got %u\n", r); + check_record(rec, 4, "1", "2", "3", "4"); + MsiCloseHandle(rec); + + r = MsiViewFetch(view, &rec); + ok(!r, "got %u\n", r); + check_record(rec, 4, "1", "4", "3", "4"); + MsiCloseHandle(rec); + + r = MsiViewFetch(view, &rec); + ok(r == ERROR_NO_MORE_ITEMS, "got %u\n", r); + MsiCloseHandle(view); + + r = MsiDatabaseOpenViewA(db, "SELECT `A`,`C` FROM `U`", &view); + ok(!r, "got %u\n", r); + r = MsiViewExecute(view, 0); + ok(!r, "got %u\n", r); + + rec = MsiCreateRecord(2); + MsiRecordSetInteger(rec, 1, 1); + MsiRecordSetInteger(rec, 2, 2); + r = MsiViewModify(view, MSIMODIFY_INSERT, rec); + ok(!r, "got %u\n", r); + + r = MsiViewModify(view, MSIMODIFY_INSERT, rec); + ok(r == ERROR_FUNCTION_FAILED, "got %u\n", r); + + MsiCloseHandle(rec); + MsiCloseHandle(view); + + r = MsiDatabaseOpenViewA(db, "SELECT * FROM `U` ORDER BY `B`", &view); + ok(!r, "got %u\n", r); + r = MsiViewExecute(view, 0); + ok(!r, "got %u\n", r); + + r = MsiViewFetch(view, &rec); + ok(!r, "got %u\n", r); + check_record(rec, 4, "1", "", "2", ""); + MsiCloseHandle(rec); + + r = MsiViewFetch(view, &rec); + ok(!r, "got %u\n", r); + check_record(rec, 4, "1", "2", "3", "4"); + MsiCloseHandle(rec); + + r = MsiViewFetch(view, &rec); + ok(!r, "got %u\n", r); + check_record(rec, 4, "1", "4", "3", "4"); + MsiCloseHandle(rec); + + r = MsiViewFetch(view, &rec); + ok(r == ERROR_NO_MORE_ITEMS, "got %u\n", r); + MsiCloseHandle(view); + + MsiCloseHandle(db); + DeleteFileA(msifile); +} + START_TEST(db) { test_msidatabase(); @@ -8924,4 +9088,5 @@ START_TEST(db) test_select_column_names(); test_primary_keys(); test_viewmodify_merge(); + test_viewmodify_insert(); }
Signed-off-by: Hans Leidekker hans@codeweavers.com