From: Piotr Caban <piotr(a)codeweavers.com> --- dlls/msado15/recordset.c | 30 ++++++++- dlls/msado15/tests/msado15.c | 114 +++++++++++++++++++++++++++++++++++ 2 files changed, 142 insertions(+), 2 deletions(-) diff --git a/dlls/msado15/recordset.c b/dlls/msado15/recordset.c index 7857ebe150c..78015b9a3ba 100644 --- a/dlls/msado15/recordset.c +++ b/dlls/msado15/recordset.c @@ -99,6 +99,7 @@ struct recordset IRowsetExactScroll *rowset_es; IRowsetChange *rowset_change; IAccessor *accessor; + IRowsetCurrentIndex *rowset_cur_idx; EditModeEnum editmode; HROW current_row; struct @@ -1640,6 +1641,9 @@ static void close_recordset( struct recordset *recordset ) if ( recordset->rowset_change && recordset->rowset_change != NO_INTERFACE ) IRowsetChange_Release( recordset->rowset_change ); recordset->rowset_change = NULL; + if ( recordset->rowset_cur_idx && recordset->rowset_cur_idx != NO_INTERFACE ) + IRowsetCurrentIndex_Release( recordset->rowset_cur_idx ); + recordset->rowset_cur_idx = NULL; for (i = 0; i < recordset->fields.count; i++) { @@ -2943,8 +2947,30 @@ static HRESULT WINAPI recordset_Seek( _Recordset *iface, VARIANT key_values, See static HRESULT WINAPI recordset_put_Index( _Recordset *iface, BSTR index ) { - FIXME( "%p, %s\n", iface, debugstr_w(index) ); - return E_NOTIMPL; + struct recordset *recordset = impl_from_Recordset( iface ); + HRESULT hr; + DBID dbid; + + TRACE( "%p, %s\n", iface, debugstr_w(index) ); + + if (!recordset->rowset_cur_idx) + { + hr = IRowset_QueryInterface( recordset->row_set, &IID_IRowsetCurrentIndex, (void **)&recordset->rowset_cur_idx ); + if (FAILED(hr) || !recordset->rowset_cur_idx) + recordset->rowset_cur_idx = NO_INTERFACE; + } + if (recordset->rowset_cur_idx == NO_INTERFACE) + return MAKE_ADO_HRESULT( adErrFeatureNotAvailable ); + + cache_release( recordset ); + + memset( &dbid, 0, sizeof(dbid) ); + dbid.eKind = DBKIND_NAME; + dbid.uName.pwszName = index; + hr = IRowsetCurrentIndex_SetIndex( recordset->rowset_cur_idx, &dbid ); + if (FAILED(hr)) return hr; + + return _Recordset_MoveFirst( iface ); } static HRESULT WINAPI recordset_get_Index( _Recordset *iface, BSTR *index ) diff --git a/dlls/msado15/tests/msado15.c b/dlls/msado15/tests/msado15.c index e3815ada6fc..910a1f13899 100644 --- a/dlls/msado15/tests/msado15.c +++ b/dlls/msado15/tests/msado15.c @@ -87,6 +87,7 @@ DEFINE_EXPECT(rowset_view_CreateView); DEFINE_EXPECT(view_chapter_OpenViewChapter); DEFINE_EXPECT(view_filter_SetFilter); DEFINE_EXPECT(chaptered_rowset_ReleaseChapter); +DEFINE_EXPECT(rowset_current_index_SetIndex); static BOOL is_bof( _Recordset *recordset ) { @@ -563,6 +564,7 @@ struct test_rowset IAccessor IAccessor_iface; IRowsetView IRowsetView_iface; IChapteredRowset IChapteredRowset_iface; + IRowsetCurrentIndex IRowsetCurrentIndex_iface; LONG refs; IViewChapter IViewChapter_iface; @@ -614,6 +616,11 @@ static inline struct test_rowset *impl_from_IChapteredRowset( IChapteredRowset * return CONTAINING_RECORD( iface, struct test_rowset, IChapteredRowset_iface ); } +static inline struct test_rowset *impl_from_IRowsetCurrentIndex( IRowsetCurrentIndex *iface ) +{ + return CONTAINING_RECORD( iface, struct test_rowset, IRowsetCurrentIndex_iface ); +} + static inline struct test_rowset *impl_from_IViewChapter( IViewChapter *iface ) { return CONTAINING_RECORD( iface, struct test_rowset, IViewChapter_iface ); @@ -1173,6 +1180,75 @@ static const struct IChapteredRowsetVtbl chaptered_rowset = chaptered_rowset_ReleaseChapter }; +static HRESULT WINAPI rowset_current_index_QueryInterface(IRowsetCurrentIndex *iface, REFIID riid, void **obj) +{ + struct test_rowset *rowset = impl_from_IRowsetCurrentIndex( iface ); + return IRowsetExactScroll_QueryInterface(&rowset->IRowsetExactScroll_iface, riid, obj); +} + +static ULONG WINAPI rowset_current_index_AddRef(IRowsetCurrentIndex *iface) +{ + struct test_rowset *rowset = impl_from_IRowsetCurrentIndex( iface ); + return IRowsetExactScroll_AddRef(&rowset->IRowsetExactScroll_iface); +} + +static ULONG WINAPI rowset_current_index_Release(IRowsetCurrentIndex *iface) +{ + struct test_rowset *rowset = impl_from_IRowsetCurrentIndex( iface ); + return IRowsetExactScroll_Release(&rowset->IRowsetExactScroll_iface); +} + +static HRESULT WINAPI rowset_current_index_GetIndexInfo(IRowsetCurrentIndex *iface, + DBORDINAL *pcKeyColumns, DBINDEXCOLUMNDESC **prgIndexColumnDesc, + ULONG *pcIndexPropertySets, DBPROPSET **prgIndexPropertySets) +{ + ok(0, "unexpected call\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI rowset_current_index_Seek(IRowsetCurrentIndex *iface, + HACCESSOR hAccessor, DBORDINAL cKeyValues, void *pData, DBSEEK dwSeekOptions) +{ + ok(0, "unexpected call\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI rowset_current_index_SetRange(IRowsetCurrentIndex *iface, + HACCESSOR hAccessor, DBORDINAL cStartKeyColumns, void *pStartData, + DBORDINAL cEndKeyColumns, void *pEndData, DBRANGE dwRangeOptions) +{ + ok(0, "unexpected call\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI rowset_current_index_GetIndex(IRowsetCurrentIndex *iface, DBID **ppIndexID) +{ + ok(0, "unexpected call\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI rowset_current_index_SetIndex(IRowsetCurrentIndex *iface, DBID *pIndexID) +{ + CHECK_EXPECT(rowset_current_index_SetIndex); + + ok(pIndexID != NULL, "pIndexID = NULL\n"); + ok(pIndexID->eKind == DBKIND_NAME, "eKind = %ld\n", pIndexID->eKind); + ok(!wcscmp(pIndexID->uName.pwszName, L"test"), "pwszName = %s\n", wine_dbgstr_w(pIndexID->uName.pwszName)); + return S_OK; +} + +static const struct IRowsetCurrentIndexVtbl rowset_current_index = +{ + rowset_current_index_QueryInterface, + rowset_current_index_AddRef, + rowset_current_index_Release, + rowset_current_index_GetIndexInfo, + rowset_current_index_Seek, + rowset_current_index_SetRange, + rowset_current_index_GetIndex, + rowset_current_index_SetIndex +}; + static HRESULT WINAPI view_chapter_QueryInterface(IViewChapter *iface, REFIID riid, void **obj) { struct test_rowset *rowset = impl_from_IViewChapter( iface ); @@ -1348,6 +1424,11 @@ static HRESULT WINAPI rowset_QueryInterface(IRowsetExactScroll *iface, REFIID ri { *obj = &rowset->IChapteredRowset_iface; } + else if (IsEqualIID(riid, &IID_IRowsetIndex) || + IsEqualIID(riid, &IID_IRowsetCurrentIndex)) + { + *obj = &rowset->IRowsetCurrentIndex_iface; + } else if (IsEqualIID(riid, &UKN_INTERFACE)) { trace("Unknown interface\n"); @@ -1611,6 +1692,7 @@ static void test_ADORecordsetConstruction(BOOL exact_scroll) ADO_LONGPTR size; DataTypeEnum type; VARIANT_BOOL b; + BSTR bstr; hr = CoCreateInstance( &CLSID_Recordset, NULL, CLSCTX_INPROC_SERVER, &IID__Recordset, (void **)&recordset ); ok( hr == S_OK, "got %08lx\n", hr ); @@ -1638,6 +1720,7 @@ static void test_ADORecordsetConstruction(BOOL exact_scroll) testrowset.IAccessor_iface.lpVtbl = &accessor; testrowset.IRowsetView_iface.lpVtbl = &rowset_view; testrowset.IChapteredRowset_iface.lpVtbl = &chaptered_rowset; + testrowset.IRowsetCurrentIndex_iface.lpVtbl = &rowset_current_index; testrowset.refs = 1; testrowset.IViewChapter_iface.lpVtbl = &view_chapter; testrowset.IViewFilter_iface.lpVtbl = &view_filter; @@ -1865,6 +1948,8 @@ static void test_ADORecordsetConstruction(BOOL exact_scroll) else CHECK_CALLED( rowset_GetRowsAt ); ok( hr == MAKE_ADO_HRESULT(adErrNoCurrentRecord), "got %08lx\n", hr ); + bstr = SysAllocString( L"test" ); + SET_EXPECT( rowset_current_index_SetIndex ); if (!exact_scroll) { SET_EXPECT( rowset_RestartPosition ); @@ -1875,8 +1960,36 @@ static void test_ADORecordsetConstruction(BOOL exact_scroll) SET_EXPECT( rowset_GetRowsAt ); SET_EXPECT( rowset_GetData ); } + hr = _Recordset_put_Index( recordset, bstr ); + ok( hr == S_OK, "got %08lx\n", hr ); + CHECK_CALLED( rowset_current_index_SetIndex ); + if (!exact_scroll) + { + CHECK_CALLED( rowset_RestartPosition ); + CHECK_CALLED( rowset_GetNextRows ); + } + else + { + CHECK_CALLED( rowset_GetRowsAt ); + CHECK_CALLED( rowset_GetData ); + } + SysFreeString( bstr ); + + SET_EXPECT( rowset_ReleaseRows ); + if (!exact_scroll) + { + SET_EXPECT( rowset_RestartPosition ); + SET_EXPECT( rowset_GetNextRows ); + } + else + { + SET_EXPECT( rowset_AddRefRows ); + SET_EXPECT( rowset_GetRowsAt ); + SET_EXPECT( rowset_GetData ); + } hr = _Recordset_MoveFirst( recordset ); ok( hr == S_OK, "got %08lx\n", hr); + CHECK_CALLED( rowset_ReleaseRows ); if (!exact_scroll) { CHECK_CALLED( rowset_RestartPosition ); @@ -1884,6 +1997,7 @@ static void test_ADORecordsetConstruction(BOOL exact_scroll) } else { + CHECK_CALLED( rowset_AddRefRows ); CHECK_CALLED( rowset_GetRowsAt ); CHECK_CALLED( rowset_GetData ); } -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/9667