Module: wine Branch: master Commit: 882e4fb2339d2c570ee1ccfcad146346cf820c00 URL: http://source.winehq.org/git/wine.git/?a=commit;h=882e4fb2339d2c570ee1ccfcad...
Author: Hans Leidekker hans@codeweavers.com Date: Fri Jan 22 12:49:11 2010 +0100
msi: Add support for updating rows in join tables.
---
dlls/msi/join.c | 112 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 files changed, 109 insertions(+), 3 deletions(-)
diff --git a/dlls/msi/join.c b/dlls/msi/join.c index b4685b5..f787c30 100644 --- a/dlls/msi/join.c +++ b/dlls/msi/join.c @@ -222,13 +222,119 @@ static UINT JOIN_get_column_info( struct tagMSIVIEW *view, return ERROR_FUNCTION_FAILED; }
-static UINT JOIN_modify( struct tagMSIVIEW *view, MSIMODIFY eModifyMode, - MSIRECORD *rec, UINT row ) +static UINT join_find_row( MSIJOINVIEW *jv, MSIRECORD *rec, UINT *row ) { - TRACE("%p %d %p\n", view, eModifyMode, rec); + LPCWSTR str; + UINT i, id, data; + + str = MSI_RecordGetString( rec, 1 ); + msi_string2idW( jv->db->strings, str, &id ); + + for (i = 0; i < jv->rows; i++) + { + JOIN_fetch_int( &jv->view, i, 1, &data ); + + if (data == id) + { + *row = i; + return ERROR_SUCCESS; + } + } + return ERROR_FUNCTION_FAILED; }
+static UINT JOIN_set_row( struct tagMSIVIEW *view, UINT row, MSIRECORD *rec, UINT mask ) +{ + MSIJOINVIEW *jv = (MSIJOINVIEW*)view; + JOINTABLE *table; + UINT i, reduced_mask = 0, r = ERROR_SUCCESS, offset = 0, col_count; + MSIRECORD *reduced; + + TRACE("%p %d %p %u %08x\n", jv, row, rec, rec->count, mask ); + + if (mask >= 1 << jv->columns) + return ERROR_INVALID_PARAMETER; + + LIST_FOR_EACH_ENTRY(table, &jv->tables, JOINTABLE, entry) + { + r = table->view->ops->get_dimensions( table->view, NULL, &col_count ); + if (r != ERROR_SUCCESS) + return r; + + reduced = MSI_CreateRecord( col_count ); + if (!reduced) + return ERROR_FUNCTION_FAILED; + + for (i = 0; i < col_count; i++) + { + r = MSI_RecordCopyField( rec, i + offset + 1, reduced, i + 1 ); + if (r != ERROR_SUCCESS) + break; + } + + offset += col_count; + reduced_mask = mask >> (jv->columns - offset) & ((1 << col_count) - 1); + + if (r == ERROR_SUCCESS) + r = table->view->ops->set_row( table->view, row, reduced, reduced_mask ); + + msiobj_release( &reduced->hdr ); + } + + return r; +} + +static UINT join_modify_update( struct tagMSIVIEW *view, MSIRECORD *rec ) +{ + MSIJOINVIEW *jv = (MSIJOINVIEW *)view; + UINT r, row; + + r = join_find_row( jv, rec, &row ); + if (r != ERROR_SUCCESS) + return r; + + return JOIN_set_row( view, row, rec, (1 << jv->columns) - 1 ); +} + +static UINT JOIN_modify( struct tagMSIVIEW *view, MSIMODIFY mode, MSIRECORD *rec, UINT row ) +{ + UINT r; + + TRACE("%p %d %p %u\n", view, mode, rec, row); + + switch (mode) + { + case MSIMODIFY_UPDATE: + return join_modify_update( view, rec ); + + case MSIMODIFY_ASSIGN: + case MSIMODIFY_DELETE: + case MSIMODIFY_INSERT: + case MSIMODIFY_INSERT_TEMPORARY: + case MSIMODIFY_MERGE: + case MSIMODIFY_REPLACE: + case MSIMODIFY_SEEK: + case MSIMODIFY_VALIDATE: + case MSIMODIFY_VALIDATE_DELETE: + case MSIMODIFY_VALIDATE_FIELD: + case MSIMODIFY_VALIDATE_NEW: + r = ERROR_FUNCTION_FAILED; + break; + + case MSIMODIFY_REFRESH: + r = ERROR_CALL_NOT_IMPLEMENTED; + break; + + default: + WARN("%p %d %p %u - unknown mode\n", view, mode, rec, row ); + r = ERROR_INVALID_PARAMETER; + break; + } + + return r; +} + static UINT JOIN_delete( struct tagMSIVIEW *view ) { MSIJOINVIEW *jv = (MSIJOINVIEW*)view;