From: Piotr Caban <piotr(a)codeweavers.com> --- dlls/msado15/recordset.c | 40 +++++++++++++++++++++++++++++++++--- dlls/msado15/tests/msado15.c | 6 ++++++ 2 files changed, 43 insertions(+), 3 deletions(-) diff --git a/dlls/msado15/recordset.c b/dlls/msado15/recordset.c index 5ae4dbcb7fd..dcb6d483801 100644 --- a/dlls/msado15/recordset.c +++ b/dlls/msado15/recordset.c @@ -2547,14 +2547,48 @@ static HRESULT WINAPI recordset__xResync( _Recordset *iface, AffectEnum affect_r static HRESULT WINAPI recordset_Update( _Recordset *iface, VARIANT fields, VARIANT values ) { struct recordset *recordset = impl_from_Recordset( iface ); + DBPENDINGSTATUS pending_status; + DBROWSTATUS *status; + HRESULT hr; + HROW *row; - FIXME( "%p, %s, %s\n", iface, debugstr_variant(&fields), debugstr_variant(&values) ); + TRACE( "%p, %s, %s\n", iface, debugstr_variant(&fields), debugstr_variant(&values) ); + if (V_VT(&fields) != VT_ERROR) + FIXME( "ignoring field list and values\n" ); - if (recordset->active_connection == NULL) + if (recordset->state == adStateClosed) return MAKE_ADO_HRESULT( adErrObjectClosed ); + if (!recordset->current_row) return MAKE_ADO_HRESULT( adErrNoCurrentRecord ); + + if (recordset->lock_type != adLockPessimistic && recordset->lock_type != adLockOptimistic) + return S_OK; + + if (!recordset->rowset_update) + { + hr = IRowset_QueryInterface( recordset->row_set, &IID_IRowsetUpdate, + (void **)&recordset->rowset_update ); + if (FAILED(hr) || !recordset->rowset_update) + recordset->rowset_update = NO_INTERFACE; + } + if (recordset->rowset_update == NO_INTERFACE) return S_OK; + hr = IRowsetUpdate_GetRowStatus( recordset->rowset_update, 0, + 1, &recordset->current_row, &pending_status ); + if (FAILED(hr)) return S_OK; + if (pending_status & (DBPENDINGSTATUS_UNCHANGED | DBPENDINGSTATUS_INVALIDROW)) return S_OK; + if (!(pending_status & (DBPENDINGSTATUS_NEW | DBPENDINGSTATUS_CHANGED | DBPENDINGSTATUS_DELETED))) + return S_OK; + + row = NULL; + status = NULL; + hr = IRowsetUpdate_Update( recordset->rowset_update, 0, 1, &recordset->current_row, NULL, &row, &status ); + if (FAILED(hr)) return hr; + if (status[0] == DBROWSTATUS_E_CANCELED) FIXME("status = DBROWSTATUS_E_CANCELED\n"); + CoTaskMemFree( row ); + CoTaskMemFree( status ); + recordset->editmode = adEditNone; - return E_NOTIMPL; + return S_OK; } static HRESULT WINAPI recordset_get_AbsolutePage( _Recordset *iface, PositionEnum_Param *pos ) diff --git a/dlls/msado15/tests/msado15.c b/dlls/msado15/tests/msado15.c index 430970caf3d..67609d9bd8f 100644 --- a/dlls/msado15/tests/msado15.c +++ b/dlls/msado15/tests/msado15.c @@ -2066,6 +2066,9 @@ static void test_ADORecordsetConstruction(BOOL exact_scroll) CHECK_CALLED(accessor_ReleaseAccessor); if (exact_scroll) CHECK_EXPECT(rowset_GetData); + hr = _Recordset_Update( recordset, missing, missing ); + ok( hr == S_OK, "got %08lx\n", hr ); + SET_EXPECT(rowset_update_GetRowStatus); SET_EXPECT(rowset_update_Undo); SET_EXPECT(rowset_AddRefRows); @@ -2080,6 +2083,9 @@ static void test_ADORecordsetConstruction(BOOL exact_scroll) hr = _Recordset_CancelUpdate( recordset ); ok( hr == MAKE_ADO_HRESULT( adErrNoCurrentRecord ), "got %08lx\n", hr ); + hr = _Recordset_Update( recordset, missing, missing ); + ok( hr == MAKE_ADO_HRESULT( adErrNoCurrentRecord ), "got %08lx\n", hr ); + V_VT(&v) = VT_BSTR; V_BSTR(&v) = SysAllocString( L"Column1 = 1" ); SET_EXPECT(rowset_ReleaseRows); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/9678