From: Hans Leidekker Subject: [PATCH 2/5] msado15: Implement Fields_get_Item. Message-Id: <20191212161225.20946-2-hans@codeweavers.com> Date: Thu, 12 Dec 2019 17:12:22 +0100 Signed-off-by: Hans Leidekker --- dlls/msado15/recordset.c | 42 ++++++++++++++++++++++++++++++++++-- dlls/msado15/tests/msado15.c | 42 ++++++++++++++++++++++++++++++++++-- 2 files changed, 80 insertions(+), 4 deletions(-) diff --git a/dlls/msado15/recordset.c b/dlls/msado15/recordset.c index a20d5920da..ff06b8789a 100644 --- a/dlls/msado15/recordset.c +++ b/dlls/msado15/recordset.c @@ -433,10 +433,48 @@ static HRESULT WINAPI fields_Refresh( Fields *iface ) return E_NOTIMPL; } +static HRESULT map_index( struct fields *fields, VARIANT *index, ULONG *ret ) +{ + ULONG i; + + if (V_VT( index ) != VT_BSTR) + { + FIXME( "variant type %u not supported\n", V_VT( index ) ); + return E_INVALIDARG; + } + + for (i = 0; i < fields->count; i++) + { + BSTR name; + BOOL match; + HRESULT hr; + + if ((hr = Field_get_Name( fields->field[i], &name )) != S_OK) return hr; + match = !wcsicmp( V_BSTR( index ), name ); + SysFreeString( name ); + if (match) + { + *ret = i; + return S_OK; + } + } + + return E_INVALIDARG; +} + static HRESULT WINAPI fields_get_Item( Fields *iface, VARIANT index, Field **obj ) { - FIXME( "%p, %s, %p\n", iface, debugstr_variant(&index), obj ); - return E_NOTIMPL; + struct fields *fields = impl_from_Fields( iface ); + HRESULT hr; + ULONG i; + + TRACE( "%p, %s, %p\n", fields, debugstr_variant(&index), obj ); + + if ((hr = map_index( fields, &index, &i )) != S_OK) return hr; + + Field_AddRef( fields->field[i] ); + *obj = fields->field[i]; + return S_OK; } static BOOL resize_fields( struct fields *fields, ULONG count ) diff --git a/dlls/msado15/tests/msado15.c b/dlls/msado15/tests/msado15.c index 03b2828d9f..800eb236fe 100644 --- a/dlls/msado15/tests/msado15.c +++ b/dlls/msado15/tests/msado15.c @@ -25,6 +25,12 @@ #define MAKE_ADO_HRESULT( err ) MAKE_HRESULT( SEVERITY_ERROR, FACILITY_CONTROL, err ) +static LONG get_refs_field( Field *field ) +{ + Field_AddRef( field ); + return Field_Release( field ); +} + static LONG get_refs_fields( Fields *fields ) { Fields_AddRef( fields ); @@ -92,9 +98,10 @@ static void test_Fields(void) { _Recordset *recordset; Fields *fields; - VARIANT val; + Field *field, *field2; + VARIANT val, index; BSTR name; - LONG count; + LONG refs, count; HRESULT hr; hr = CoCreateInstance( &CLSID_Recordset, NULL, CLSCTX_INPROC_SERVER, &IID__Recordset, (void **)&recordset ); @@ -127,6 +134,37 @@ static void test_Fields(void) hr = Fields_get_Count( fields, &count ); ok( count == 2, "got %d\n", count ); + /* handing out field object doesn't add reference to fields or recordset object */ + name = SysAllocString( L"field" ); + V_VT( &index ) = VT_BSTR; + V_BSTR( &index ) = name; + refs = get_refs_recordset( recordset ); + ok( refs == 2, "got %d\n", refs ); + refs = get_refs_fields( fields ); + ok( refs == 1, "got %d\n", refs ); + hr = Fields_get_Item( fields, index, &field ); + ok( hr == S_OK, "got %08x\n", hr ); + refs = get_refs_field( field ); + ok( refs == 1, "got %d\n", refs ); + refs = get_refs_recordset( recordset ); + ok( refs == 2, "got %d\n", refs ); + refs = get_refs_fields( fields ); + ok( refs == 1, "got %d\n", refs ); + + /* calling get_Item again returns the same object and adds reference */ + hr = Fields_get_Item( fields, index, &field2 ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( field2 == field, "expected same object\n" ); + refs = get_refs_field( field2 ); + ok( refs == 2, "got %d\n", refs ); + refs = get_refs_recordset( recordset ); + ok( refs == 2, "got %d\n", refs ); + refs = get_refs_fields( fields ); + ok( refs == 1, "got %d\n", refs ); + Field_Release( field2 ); + SysFreeString( name ); + + Field_Release( field ); Fields_Release( fields ); _Recordset_Release( recordset ); } -- 2.20.1