[PATCH 0/4] MR9993: msado15: Add _Recordset::Find implementation.
From: Piotr Caban <piotr@codeweavers.com> --- dlls/msado15/tests/msado15.c | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/dlls/msado15/tests/msado15.c b/dlls/msado15/tests/msado15.c index 6d7d9b88ea1..026545cedb4 100644 --- a/dlls/msado15/tests/msado15.c +++ b/dlls/msado15/tests/msado15.c @@ -2193,6 +2193,38 @@ static void test_ADORecordsetConstruction(BOOL exact_scroll) } VariantClear(&v); + testrowset.filter_chapter = FALSE; + V_VT(&v) = VT_BSTR; + V_BSTR(&v) = NULL; + SET_EXPECT(rowset_AddRefRows); + SET_EXPECT(rowset_ReleaseRows); + if (exact_scroll) + { + SET_EXPECT(rowset_GetRowsAt); + SET_EXPECT(rowset_GetData); + } + else + { + SET_EXPECT(rowset_RestartPosition); + SET_EXPECT(rowset_GetNextRows); + } + SET_EXPECT(chaptered_rowset_ReleaseChapter); + hr = _Recordset_put_Filter( recordset, v ); + todo_wine ok( hr == S_OK, "got %08lx\n", hr ); + todo_wine CHECK_CALLED(rowset_AddRefRows); + todo_wine CHECK_CALLED(rowset_ReleaseRows); + if (exact_scroll) + { + todo_wine CHECK_CALLED(rowset_GetRowsAt); + todo_wine CHECK_CALLED(rowset_GetData); + } + else + { + todo_wine CHECK_CALLED(rowset_RestartPosition); + todo_wine CHECK_CALLED(rowset_GetNextRows); + } + todo_wine CHECK_CALLED(chaptered_rowset_ReleaseChapter); + Fields_Release(fields); ADORecordsetConstruction_Release(construct); SET_EXPECT( rowset_ReleaseRows ); @@ -2201,7 +2233,6 @@ static void test_ADORecordsetConstruction(BOOL exact_scroll) ok( !_Recordset_Release( recordset ), "_Recordset not released\n" ); todo_wine CHECK_CALLED(rowset_ReleaseRows ); CHECK_CALLED(accessor_ReleaseAccessor); - todo_wine CHECK_CALLED(chaptered_rowset_ReleaseChapter); ok( testrowset.refs == 1, "got %ld\n", testrowset.refs ); } -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/9993
From: Piotr Caban <piotr@codeweavers.com> --- dlls/msado15/recordset.c | 100 +++++++++++++++++++++------------------ 1 file changed, 54 insertions(+), 46 deletions(-) diff --git a/dlls/msado15/recordset.c b/dlls/msado15/recordset.c index 1495c9b4dc4..42e46b104c3 100644 --- a/dlls/msado15/recordset.c +++ b/dlls/msado15/recordset.c @@ -233,6 +233,55 @@ static HRESULT get_bookmark( struct recordset *recordset, HROW row, VARIANT *boo return S_OK; } +static HRESULT get_bookmark_data( VARIANT *bookmark, const BYTE **data, DBBKMARK *len, int *tmp ) +{ + if (V_VT(bookmark) == VT_R8) + { + if (isinf(V_R8(bookmark))) + { + if (V_R8(bookmark) < 0) *(BYTE *)tmp = DBBMK_FIRST; + else *(BYTE *)tmp = DBBMK_LAST; + *data = (BYTE *)tmp; + *len = 1; + } + else + { + *tmp = V_R8(bookmark); + *data = (BYTE *)tmp; + *len = sizeof(*tmp); + } + } + else if (V_VT(bookmark) == VT_I8) + { + *data = (BYTE *)&V_I8(bookmark); + *len = sizeof(V_I8(bookmark)); + } + else if (V_VT(bookmark) == VT_EMPTY) + { + *data = NULL; + *len = 0; + } + else if (V_VT(bookmark) & (VT_ARRAY | VT_UI1)) + { + HRESULT hr = SafeArrayLock(V_ARRAY(bookmark)); + if (FAILED(hr)) return hr; + *data = V_ARRAY(bookmark)->pvData; + *len = V_ARRAY(bookmark)->rgsabound[0].cElements; + } + else + { + WARN("unexpected bookmark %s\n", wine_dbgstr_variant(bookmark)); + return E_FAIL; + } + return S_OK; +} + +static void release_bookmark_data( VARIANT *bookmark ) +{ + if (V_VT(bookmark) & VT_ARRAY) + SafeArrayUnlock(V_ARRAY(bookmark)); +} + static HRESULT cache_get( struct recordset *recordset, BOOL forward ) { int dir = forward ? 1 : -1; @@ -283,53 +332,13 @@ static HRESULT cache_get( struct recordset *recordset, BOOL forward ) if (recordset->bookmark_hacc) { const BYTE *data; - LONGLONG i8_buf; - BYTE byte_buf; DBBKMARK len; int int_buf; - if (V_VT(&recordset->bookmark) == VT_R8) - { - if (isinf(V_R8(&recordset->bookmark))) - { - data = (BYTE *)&byte_buf; - if (V_R8(&recordset->bookmark) < 0) - { - byte_buf = DBBMK_FIRST; - if (!forward) off -= 2; - } - else - { - byte_buf = DBBMK_LAST; - if (forward) off += 2; - } - len = sizeof(byte_buf); - } - else - { - data = (BYTE *)&int_buf; - int_buf = V_R8(&recordset->bookmark); - len = sizeof(int_buf); - } - } - else if (V_VT(&recordset->bookmark) == VT_I8) - { - data = (BYTE *)&i8_buf; - i8_buf = V_I8(&recordset->bookmark); - len = sizeof(i8_buf); - } - else if (V_VT(&recordset->bookmark) == VT_EMPTY) - { - data = NULL; - len = 0; - } - else - { - hr = SafeArrayLock(V_ARRAY(&recordset->bookmark)); - if (FAILED(hr)) return hr; - data = V_ARRAY(&recordset->bookmark)->pvData; - len = V_ARRAY(&recordset->bookmark)->rgsabound[0].cElements; - } + hr = get_bookmark_data(&recordset->bookmark, &data, &len, &int_buf); + if (FAILED(hr)) return hr; + if (!forward && len == 1 && *data == DBBMK_FIRST) off -= 2; + else if (forward && len == 1 && *data == DBBMK_LAST) off += 2; if (!data) { @@ -340,8 +349,7 @@ static HRESULT cache_get( struct recordset *recordset, BOOL forward ) hr = IRowsetLocate_GetRowsAt(recordset->rowset_locate, 0, 0, len, data, off, fetch, &count, &recordset->cache.rows); } - if (V_VT(&recordset->bookmark) & VT_ARRAY) - SafeArrayUnlock(V_ARRAY(&recordset->bookmark)); + release_bookmark_data(&recordset->bookmark); if (hr == DB_E_BADSTARTPOSITION) { -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/9993
From: Piotr Caban <piotr@codeweavers.com> --- dlls/msado15/recordset.c | 248 ++++++++++++++++++++++++++++++++++- dlls/msado15/tests/msado15.c | 4 - 2 files changed, 246 insertions(+), 6 deletions(-) diff --git a/dlls/msado15/recordset.c b/dlls/msado15/recordset.c index 42e46b104c3..d96411b022a 100644 --- a/dlls/msado15/recordset.c +++ b/dlls/msado15/recordset.c @@ -113,6 +113,7 @@ struct recordset IRowset *row_set; IRowsetLocate *rowset_locate; IRowsetExactScroll *rowset_es; + IRowsetFind *rowset_find; IRowsetChange *rowset_change; IRowsetUpdate *rowset_update; IAccessor *accessor; @@ -1717,6 +1718,9 @@ static void close_recordset( struct recordset *recordset ) if ( recordset->rowset_es && recordset->rowset_es != NO_INTERFACE ) IRowsetExactScroll_Release( recordset->rowset_es ); recordset->rowset_es = NULL; + if ( recordset->rowset_find) + IRowsetFind_Release( recordset->rowset_find ); + recordset->rowset_find = NULL; if ( recordset->rowset_change && recordset->rowset_change != NO_INTERFACE ) IRowsetChange_Release( recordset->rowset_change ); recordset->rowset_change = NULL; @@ -3272,12 +3276,250 @@ static HRESULT WINAPI recordset_put_MarshalOptions( _Recordset *iface, MarshalOp return E_NOTIMPL; } +static HRESULT parse_criteria( const WCHAR **str, BSTR *col, DBCOMPAREOP *op, BSTR *val ) +{ + const WCHAR *p = *str, *col_b, *col_e, *val_b, *val_e; + UINT i, val_len; + + while (*p && iswspace( *p )) p++; + if (!*p) return MAKE_ADO_HRESULT( adErrInvalidArgument ); + if (*p == '[') + { + col_b = ++p; + while (*p && *p != ']') p++; + col_e = p; + if (*p) p++; + } + else + { + col_b = p; + while (*p && !iswspace( *p ) && *p != '=') p++; + col_e = p; + } + if (!*p || col_b == col_e) return MAKE_ADO_HRESULT( adErrInvalidArgument ); + + while (*p && iswspace( *p )) p++; + switch(*p) + { + case '>': + if (p[1] == '=') + { + *op = DBCOMPAREOPS_GE; + p += 2; + } + else + { + *op = DBCOMPAREOPS_GT; + p++; + } + break; + case '<': + if (p[1] == '=') + { + *op = DBCOMPAREOPS_LE; + p += 2; + } + else if (p[1] == '>') + { + *op = DBCOMPAREOPS_NE; + p += 2; + } + else + { + *op = DBCOMPAREOPS_LT; + p++; + } + break; + case '=': + *op = DBCOMPAREOPS_EQ; + p++; + break; + default: + if (!wcsnicmp(p, L"like", 4)) + { + *op = DBCOMPAREOPS_BEGINSWITH; + p += 4; + break; + } + + FIXME( "unsupported operator %s\n", debugstr_w(p) ); + return MAKE_ADO_HRESULT( adErrInvalidArgument ); + } + + while (*p && iswspace( *p )) p++; + if (!*p) return MAKE_ADO_HRESULT( adErrInvalidArgument ); + if (*p == '\'') + { + val_b = ++p; + val_len = 0; + while (*p && (*p != '\'' || p[1] == '\'')) + { + if (*p == '\'') p++; + p++; + val_len++; + } + } + else if (*p == '#') + { + val_b = ++p; + while (*p && *p != '#') p++; + val_len = p - val_b; + } + else + { + val_b = p; + while (*p && !iswspace( *p )) p++; + val_len = p - val_b; + } + val_e = p; + if (*p) p++; + + if (*op == DBCOMPAREOPS_BEGINSWITH) + { + if (*val_b == '*' && (val_e == val_b + 1 || val_e[-1] != '*')) + return MAKE_ADO_HRESULT( adErrInvalidArgument ); + + if (val_b == val_e || val_e[-1] != '*') + { + *op = DBCOMPAREOPS_EQ; + } + else if (*val_b == '*') + { + *op = DBCOMPAREOPS_CONTAINS; + val_b++; + val_e--; + val_len -= 2; + } + else + { + val_e--; + val_len--; + } + } + + *col = SysAllocStringLen( col_b, col_e - col_b ); + if (!col) return E_OUTOFMEMORY; + + *val = SysAllocStringLen( val_b, val_len ); + if (!*val) + { + SysFreeString( *col ); + return E_OUTOFMEMORY; + } + if (val_len != val_e - val_b) + { + for (i = 0, val_len = 0; i < val_e - val_b; i++) + { + (*val)[val_len++] = val_b[i]; + if (val_b[i] == '\'') i++; + } + } + + while (*p && iswspace( *p )) p++; + *str = p; + return S_OK; +} + static HRESULT WINAPI recordset_Find( _Recordset *iface, BSTR criteria, LONG skip_records, SearchDirectionEnum search_direction, VARIANT start ) { - FIXME( "%p, %s, %ld, %d, %s\n", iface, debugstr_w(criteria), skip_records, search_direction, + struct recordset *recordset = impl_from_Recordset( iface ); + BOOL free_bookmark = FALSE; + HROW row = 0, *rows = &row; + DBCOUNTITEM obtained; + const BYTE *bm_data; + const WCHAR *crit; + DBBKMARK bm_len; + VARIANT_BOOL b; + DBCOMPAREOP op; + HACCESSOR hacc; + BSTR col, val; + int int_buf; + HRESULT hr; + VARIANT v; + + TRACE( "%p, %s, %ld, %d, %s\n", iface, debugstr_w(criteria), skip_records, search_direction, debugstr_variant(&start) ); - return E_NOTIMPL; + + if (!criteria) return MAKE_ADO_HRESULT( adErrInvalidArgument ); + if (search_direction != adSearchForward && search_direction != adSearchBackward) + return MAKE_ADO_HRESULT( adErrInvalidArgument ); + if (!recordset->rowset_find) return MAKE_ADO_HRESULT( adErrFeatureNotAvailable ); + + if (!recordset->current_row) return S_FALSE; + + if (V_VT(&start) == VT_ERROR && V_ERROR(&start) == DISP_E_PARAMNOTFOUND) + { + if (!recordset->bookmark_hacc) + VariantInit( &start ); + else + { + hr = get_bookmark(recordset, recordset->current_row, &start); + if (FAILED(hr)) return hr; + free_bookmark = TRUE; + } + } + + crit = criteria; + hr = parse_criteria( &crit, &col, &op, &val ); + if (FAILED(hr)) return hr; + if (*crit) + { + SysFreeString( col ); + SysFreeString( val ); + if (free_bookmark) VariantClear( &start ); + return MAKE_ADO_HRESULT( adErrInvalidArgument ); + } + + V_VT(&v) = VT_BSTR; + V_BSTR(&v) = col; + hr = get_accessor( recordset, &v, &hacc ); + SysFreeString( col ); + if (SUCCEEDED(hr)) + hr = get_bookmark_data( &start, &bm_data, &bm_len, &int_buf ); + if (FAILED(hr)) + { + SysFreeString( val ); + if (free_bookmark) VariantClear( &start ); + return hr; + } + + if (SUCCEEDED(_Recordset_Supports( &recordset->Recordset_iface, adHoldRecords, &b )) && b && + SUCCEEDED(IRowset_AddRefRows( recordset->row_set, 1, &recordset->current_row, NULL, NULL ))) + { + row = recordset->current_row; + } + cache_release( recordset ); + recordset->current_row = row; + + V_VT(&v) = VT_BSTR; + V_BSTR(&v) = val; + if (!bm_len && search_direction == adSearchForward) + skip_records--; + hr = IRowsetFind_FindNextRow( recordset->rowset_find, DB_NULL_HCHAPTER, hacc, &v, op, + bm_len, bm_data, skip_records, search_direction, &obtained, &rows ); + SysFreeString( val ); + release_bookmark_data( &start ); + if (free_bookmark) VariantClear( &start ); + IAccessor_ReleaseAccessor( recordset->accessor, hacc, NULL ); + if (FAILED(hr)) return hr; + + if (recordset->bookmark_hacc) + { + hr = get_bookmark(recordset, row, &v); + if (FAILED(hr)) + { + IRowset_ReleaseRows( recordset->row_set, 1, &row, NULL, NULL, NULL ); + return hr; + } + VariantClear(&recordset->bookmark); + recordset->bookmark = v; + } + + if (recordset->current_row) + IRowset_ReleaseRows( recordset->row_set, 1, &recordset->current_row, NULL, NULL, NULL); + recordset->current_row = row; + return S_OK; } static HRESULT WINAPI recordset_Cancel( _Recordset *iface ) @@ -3959,6 +4201,8 @@ static HRESULT WINAPI rsconstruction_put_Rowset(ADORecordsetConstruction *iface, hr = IRowset_QueryInterface( rowset, &IID_IRowsetLocate, (void**)&recordset->rowset_locate ); if (SUCCEEDED(hr)) init_bookmark( recordset ); + + IRowset_QueryInterface( rowset, &IID_IRowsetFind, (void**)&recordset->rowset_find ); return S_OK; } diff --git a/dlls/msado15/tests/msado15.c b/dlls/msado15/tests/msado15.c index 026545cedb4..76b60d73272 100644 --- a/dlls/msado15/tests/msado15.c +++ b/dlls/msado15/tests/msado15.c @@ -69,7 +69,6 @@ static char mdbpath[MAX_PATH]; }while(0) DEFINE_EXPECT(rowset_QI_IDBAsynchStatus); -DEFINE_EXPECT(rowset_QI_IRowsetFind); DEFINE_EXPECT(rowset_info_GetProperties); DEFINE_EXPECT(column_info_GetColumnInfo); DEFINE_EXPECT(rowset_GetNextRows); @@ -1474,7 +1473,6 @@ static HRESULT WINAPI rowset_QueryInterface(IRowsetExactScroll *iface, REFIID ri } else if (IsEqualIID(riid, &IID_IRowsetFind)) { - CHECK_EXPECT(rowset_QI_IRowsetFind); return E_NOINTERFACE; } else if (IsEqualIID(riid, &IID_IRowsetView)) @@ -1797,7 +1795,6 @@ static void test_ADORecordsetConstruction(BOOL exact_scroll) ok( lock_type == adLockReadOnly, "lock_type = %d\n", lock_type ); SET_EXPECT( rowset_info_GetProperties ); - SET_EXPECT( rowset_QI_IRowsetFind ); if (exact_scroll) { SET_EXPECT( column_info_GetColumnInfo ); @@ -1806,7 +1803,6 @@ static void test_ADORecordsetConstruction(BOOL exact_scroll) SET_EXPECT( rowset_QI_IDBAsynchStatus ); hr = ADORecordsetConstruction_put_Rowset( construct, rowset ); CHECK_CALLED( rowset_info_GetProperties ); - todo_wine CHECK_CALLED( rowset_QI_IRowsetFind ); if (exact_scroll) { CHECK_CALLED( column_info_GetColumnInfo ); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/9993
From: Piotr Caban <piotr@codeweavers.com> --- dlls/msado15/tests/msado15.c | 156 ++++++++++++++++++++++++++++++++++- 1 file changed, 152 insertions(+), 4 deletions(-) diff --git a/dlls/msado15/tests/msado15.c b/dlls/msado15/tests/msado15.c index 76b60d73272..d6881b70e80 100644 --- a/dlls/msado15/tests/msado15.c +++ b/dlls/msado15/tests/msado15.c @@ -93,6 +93,7 @@ DEFINE_EXPECT(rowset_current_index_GetIndexInfo); DEFINE_EXPECT(rowset_current_index_Seek); DEFINE_EXPECT(rowset_current_index_GetIndex); DEFINE_EXPECT(rowset_current_index_SetIndex); +DEFINE_EXPECT(rowset_find_FindNextRow); DEFINE_EXPECT(open_rowset_QI_ISessionProperties); DEFINE_EXPECT(open_rowset_QI_IBindResource); DEFINE_EXPECT(open_rowset_QI_ICreateRow); @@ -578,6 +579,7 @@ struct test_rowset IRowsetView IRowsetView_iface; IChapteredRowset IChapteredRowset_iface; IRowsetCurrentIndex IRowsetCurrentIndex_iface; + IRowsetFind IRowsetFind_iface; LONG refs; IViewChapter IViewChapter_iface; @@ -635,6 +637,11 @@ static inline struct test_rowset *impl_from_IRowsetCurrentIndex( IRowsetCurrentI return CONTAINING_RECORD( iface, struct test_rowset, IRowsetCurrentIndex_iface ); } +static inline struct test_rowset *impl_from_IRowsetFind( IRowsetFind *iface ) +{ + return CONTAINING_RECORD( iface, struct test_rowset, IRowsetFind_iface ); +} + static inline struct test_rowset *impl_from_IViewChapter( IViewChapter *iface ) { return CONTAINING_RECORD( iface, struct test_rowset, IViewChapter_iface ); @@ -745,7 +752,7 @@ static HRESULT WINAPI rowset_info_GetProperties(IRowsetInfo *iface, const ULONG break; case DBPROP_IRowsetFind: V_VT(v) = VT_BOOL; - V_BOOL(v) = VARIANT_FALSE; + V_BOOL(v) = VARIANT_TRUE; break; case DBPROP_IRowsetRefresh: V_VT(v) = VT_BOOL; @@ -1305,6 +1312,71 @@ static const struct IRowsetCurrentIndexVtbl rowset_current_index = rowset_current_index_SetIndex }; +static HRESULT WINAPI rowset_find_QueryInterface(IRowsetFind *iface, REFIID riid, void **obj) +{ + struct test_rowset *rowset = impl_from_IRowsetFind( iface ); + return IRowsetExactScroll_QueryInterface(&rowset->IRowsetExactScroll_iface, riid, obj); +} + +static ULONG WINAPI rowset_find_AddRef(IRowsetFind *iface) +{ + struct test_rowset *rowset = impl_from_IRowsetFind( iface ); + return IRowsetExactScroll_AddRef(&rowset->IRowsetExactScroll_iface); +} + +static ULONG WINAPI rowset_find_Release(IRowsetFind *iface) +{ + struct test_rowset *rowset = impl_from_IRowsetFind( iface ); + return IRowsetExactScroll_Release(&rowset->IRowsetExactScroll_iface); +} + +static HRESULT WINAPI rowset_find_FindNextRow(IRowsetFind *iface, + HCHAPTER chapter, HACCESSOR hacc, void *find_value, DBCOMPAREOP compare_op, + DBBKMARK bookmark_size, const BYTE *bookmark, DBROWOFFSET offset, + DBROWCOUNT rows, DBCOUNTITEM *obtained, HROW **hrows) +{ + struct haccessor *accessor = (struct haccessor *)hacc; + VARIANT *v = find_value; + + + CHECK_EXPECT(rowset_find_FindNextRow); + + ok(!chapter, "chapter = %Id\n", chapter); + ok(accessor->binding.iOrdinal == 1, "accessor->binding.iOrdinal = %Id\n", accessor->binding.iOrdinal); + ok(accessor->binding.wType == VT_VARIANT, "accessor->binding.wType = %d\n", accessor->binding.wType); + ok(accessor->binding.dwPart == DBPART_VALUE, "accessor->binding.dwPart = %ld\n", accessor->binding.dwPart); + ok(V_VT(v) == VT_BSTR, "v = %s\n", wine_dbgstr_variant(v)); + ok(!wcscmp(V_BSTR(v), L"1'1"), "v = %s\n", wine_dbgstr_variant(v)); + ok(compare_op == DBCOMPAREOPS_EQ, "compare_op = %ld\n", compare_op); + if (!bookmark_size) + { + ok(!bookmark, "bookmark != NULL\n"); + ok(offset == -1, "offset = %Id\n", offset); + } + else + { + ok(offset == 0, "offset = %Id\n", offset); + ok(bookmark_size == 4, "bookmark_size = %Id\n", bookmark_size); + ok(*(int*)bookmark == 1 || *(int*)bookmark == 2, "bookmark = %d\n", *(int*)bookmark); + } + ok(rows == 1, "rows = %Id\n", rows); + ok(obtained != NULL, "obtained = NULL\n"); + ok(hrows != NULL, "hrows == NULL\n"); + ok(*hrows != NULL, "*hrows == NULL\n"); + + *obtained = 1; + (*hrows)[0] = 2; + return S_OK; +} + +static const struct IRowsetFindVtbl rowset_find = +{ + rowset_find_QueryInterface, + rowset_find_AddRef, + rowset_find_Release, + rowset_find_FindNextRow +}; + static HRESULT WINAPI view_chapter_QueryInterface(IViewChapter *iface, REFIID riid, void **obj) { struct test_rowset *rowset = impl_from_IViewChapter( iface ); @@ -1473,7 +1545,7 @@ static HRESULT WINAPI rowset_QueryInterface(IRowsetExactScroll *iface, REFIID ri } else if (IsEqualIID(riid, &IID_IRowsetFind)) { - return E_NOINTERFACE; + *obj = &rowset->IRowsetFind_iface; } else if (IsEqualIID(riid, &IID_IRowsetView)) { @@ -1737,6 +1809,15 @@ static const struct IRowsetExactScrollVtbl rowset_vtbl = static void test_ADORecordsetConstruction(BOOL exact_scroll) { + static const WCHAR *find_criteria[] = + { + L"Column1 = #1'1# ", + L"[Column1] = 1'1\t", + L" Column1 = '1''1' ", + L"Column1 LIKE 1'1", + L"Column1 like 1'1" + }; + _Recordset *recordset; ADORecordsetConstruction *construct; Fields *fields = NULL; @@ -1752,6 +1833,7 @@ static void test_ADORecordsetConstruction(BOOL exact_scroll) DataTypeEnum type; VARIANT_BOOL b; BSTR bstr; + int i; hr = CoCreateInstance( &CLSID_Recordset, NULL, CLSCTX_INPROC_SERVER, &IID__Recordset, (void **)&recordset ); ok( hr == S_OK, "got %08lx\n", hr ); @@ -1780,6 +1862,7 @@ static void test_ADORecordsetConstruction(BOOL exact_scroll) testrowset.IRowsetView_iface.lpVtbl = &rowset_view; testrowset.IChapteredRowset_iface.lpVtbl = &chaptered_rowset; testrowset.IRowsetCurrentIndex_iface.lpVtbl = &rowset_current_index; + testrowset.IRowsetFind_iface.lpVtbl = &rowset_find; testrowset.refs = 1; testrowset.IViewChapter_iface.lpVtbl = &view_chapter; testrowset.IViewFilter_iface.lpVtbl = &view_filter; @@ -1861,7 +1944,7 @@ static void test_ADORecordsetConstruction(BOOL exact_scroll) hr = _Recordset_Supports( recordset, adFind, &b ); ok( hr == S_OK, "got %08lx\n", hr); - ok( b == VARIANT_FALSE, "b = %x\n", b); + ok( b == VARIANT_TRUE, "b = %x\n", b); hr = _Recordset_Supports( recordset, adSeek, &b ); ok( hr == S_OK, "got %08lx\n", hr); @@ -2151,8 +2234,71 @@ static void test_ADORecordsetConstruction(BOOL exact_scroll) hr = _Recordset_Update( recordset, missing, missing ); ok( hr == MAKE_ADO_HRESULT( adErrNoCurrentRecord ), "got %08lx\n", hr ); + if (!exact_scroll) + { + SET_EXPECT( rowset_ReleaseRows ); + SET_EXPECT( rowset_RestartPosition ); + SET_EXPECT( rowset_GetNextRows ); + } + else + { + SET_EXPECT( rowset_GetRowsAt ); + SET_EXPECT( rowset_GetData ); + } + hr = _Recordset_MoveFirst( recordset ); + ok( hr == S_OK, "got %08lx\n", hr); + if (!exact_scroll) + { + todo_wine CHECK_CALLED( rowset_ReleaseRows ); + CHECK_CALLED( rowset_RestartPosition ); + CHECK_CALLED( rowset_GetNextRows ); + } + else + { + CHECK_CALLED( rowset_GetRowsAt ); + CHECK_CALLED( rowset_GetData ); + } + + if (exact_scroll) SET_EXPECT(rowset_GetData); + hr = _Recordset_Find( recordset, (BSTR)L"Column1", 0, adSearchForward, missing ); + ok(hr == MAKE_ADO_HRESULT( adErrInvalidArgument ), "got %08lx\n", hr ); + if (exact_scroll) CHECK_CALLED(rowset_GetData); + + if (exact_scroll) SET_EXPECT(rowset_GetData); + hr = _Recordset_Find( recordset, (BSTR)L"Column1 = 1 1", 0, adSearchForward, missing ); + ok(hr == MAKE_ADO_HRESULT( adErrInvalidArgument ), "got %08lx\n", hr ); + if (exact_scroll) CHECK_CALLED(rowset_GetData); + + if (exact_scroll) SET_EXPECT(rowset_GetData); + hr = _Recordset_Find( recordset, (BSTR)L"Column2 = 1", 0, adSearchForward, missing ); + ok(hr == MAKE_ADO_HRESULT( adErrItemNotFound ), "got %08lx\n", hr ); + if (exact_scroll) CHECK_CALLED(rowset_GetData); + + for (i = 0; i < ARRAY_SIZE(find_criteria); i++) + { + winetest_push_context( "%d", i ); + + SET_EXPECT(accessor_AddRefAccessor); + SET_EXPECT(rowset_AddRefRows); + SET_EXPECT(rowset_ReleaseRows); + SET_EXPECT(rowset_find_FindNextRow); + if (exact_scroll) SET_EXPECT(rowset_GetData); + SET_EXPECT(accessor_ReleaseAccessor); + hr = _Recordset_Find( recordset, (BSTR)find_criteria[i], + 0, adSearchForward, missing ); + ok( hr == S_OK, "got %08lx\n", hr ); + CHECK_CALLED(accessor_AddRefAccessor); + CHECK_CALLED(rowset_AddRefRows); + CHECK_CALLED(rowset_ReleaseRows); + CHECK_CALLED(rowset_find_FindNextRow); + if (exact_scroll) CHECK_CALLED(rowset_GetData); + CHECK_CALLED(accessor_ReleaseAccessor); + winetest_pop_context(); + } + V_VT(&v) = VT_BSTR; V_BSTR(&v) = SysAllocString( L"Column1 = 1" ); + SET_EXPECT(rowset_AddRefRows); SET_EXPECT(rowset_ReleaseRows); SET_EXPECT(accessor_AddRefAccessor); SET_EXPECT(rowset_view_CreateView); @@ -2171,6 +2317,7 @@ static void test_ADORecordsetConstruction(BOOL exact_scroll) } hr = _Recordset_put_Filter( recordset, v ); todo_wine ok( hr == S_OK, "got %08lx\n", hr ); + todo_wine CHECK_CALLED(rowset_AddRefRows); todo_wine CHECK_CALLED(rowset_ReleaseRows); todo_wine CHECK_CALLED(accessor_AddRefAccessor); todo_wine CHECK_CALLED(rowset_view_CreateView); @@ -2227,7 +2374,7 @@ static void test_ADORecordsetConstruction(BOOL exact_scroll) SET_EXPECT(accessor_ReleaseAccessor); SET_EXPECT(chaptered_rowset_ReleaseChapter); ok( !_Recordset_Release( recordset ), "_Recordset not released\n" ); - todo_wine CHECK_CALLED(rowset_ReleaseRows ); + CHECK_CALLED(rowset_ReleaseRows ); CHECK_CALLED(accessor_ReleaseAccessor); ok( testrowset.refs == 1, "got %ld\n", testrowset.refs ); } @@ -3615,6 +3762,7 @@ static HRESULT WINAPI open_rowset_OpenRowset(IOpenRowset *iface, IUnknown *unk_o open_rowset_test.IRowsetView_iface.lpVtbl = &rowset_view; open_rowset_test.IChapteredRowset_iface.lpVtbl = &chaptered_rowset; open_rowset_test.IRowsetCurrentIndex_iface.lpVtbl = &rowset_current_index; + open_rowset_test.IRowsetFind_iface.lpVtbl = &rowset_find; open_rowset_test.refs = 1; open_rowset_test.IViewChapter_iface.lpVtbl = &view_chapter; open_rowset_test.IViewFilter_iface.lpVtbl = &view_filter; -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/9993
participants (2)
-
Piotr Caban -
Piotr Caban (@piotr)