msado15/tests: Add ADORecordsetConstruction tests.

Signed-off-by: Alistair Leslie-Hughes <leslie_alistair@hotmail.com>
Signed-off-by: Hans Leidekker <hans@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Alistair Leslie-Hughes 2020-11-18 20:42:20 +11:00 committed by Alexandre Julliard
parent 65d917402f
commit 36d8147c13
1 changed files with 346 additions and 0 deletions

View File

@ -23,6 +23,9 @@
#include <olectl.h>
#include <msado15_backcompat.h>
#include "wine/test.h"
#include "msdasql.h"
DEFINE_GUID(DBPROPSET_ROWSET, 0xc8b522be, 0x5cf3, 0x11ce, 0xad, 0xe5, 0x00, 0xaa, 0x00, 0x44, 0x77, 0x3d);
#define MAKE_ADO_HRESULT( err ) MAKE_HRESULT( SEVERITY_ERROR, FACILITY_CONTROL, err )
@ -288,6 +291,348 @@ static void test_Recordset(void)
_Recordset_Release( recordset );
}
/* This interface is queried for but is not documented anywhere. */
DEFINE_GUID(UKN_INTERFACE, 0x6f1e39e1, 0x05c6, 0x11d0, 0xa7, 0x8b, 0x00, 0xaa, 0x00, 0xa3, 0xf0, 0x0d);
struct test_rowset
{
IRowset IRowset_iface;
IRowsetInfo IRowsetInfo_iface;
IColumnsInfo IColumnsInfo_iface;
LONG refs;
};
static inline struct test_rowset *impl_from_IRowset( IRowset *iface )
{
return CONTAINING_RECORD( iface, struct test_rowset, IRowset_iface );
}
static inline struct test_rowset *impl_from_IRowsetInfo( IRowsetInfo *iface )
{
return CONTAINING_RECORD( iface, struct test_rowset, IRowsetInfo_iface );
}
static inline struct test_rowset *impl_from_IColumnsInfo( IColumnsInfo *iface )
{
return CONTAINING_RECORD( iface, struct test_rowset, IColumnsInfo_iface );
}
static HRESULT WINAPI rowset_info_QueryInterface(IRowsetInfo *iface, REFIID riid, void **obj)
{
struct test_rowset *rowset = impl_from_IRowsetInfo( iface );
return IRowset_QueryInterface(&rowset->IRowset_iface, riid, obj);
}
static ULONG WINAPI rowset_info_AddRef(IRowsetInfo *iface)
{
struct test_rowset *rowset = impl_from_IRowsetInfo( iface );
return IRowset_AddRef(&rowset->IRowset_iface);
}
static ULONG WINAPI rowset_info_Release(IRowsetInfo *iface)
{
struct test_rowset *rowset = impl_from_IRowsetInfo( iface );
return IRowset_Release(&rowset->IRowset_iface);
}
static HRESULT WINAPI rowset_info_GetProperties(IRowsetInfo *iface, const ULONG count,
const DBPROPIDSET propertyidsets[], ULONG *out_count, DBPROPSET **propertysets1)
{
ok( count == 2, "got %d\n", count );
ok( IsEqualIID(&DBPROPSET_ROWSET, &propertyidsets[0].guidPropertySet), "got %s\n", wine_dbgstr_guid(&propertyidsets[0].guidPropertySet));
ok( propertyidsets[0].cPropertyIDs == 17, "got %d\n", propertyidsets[0].cPropertyIDs );
ok( IsEqualIID(&DBPROPSET_PROVIDERROWSET, &propertyidsets[1].guidPropertySet), "got %s\n", wine_dbgstr_guid(&propertyidsets[1].guidPropertySet));
ok( propertyidsets[1].cPropertyIDs == 1, "got %d\n", propertyidsets[1].cPropertyIDs );
return E_NOTIMPL;
}
static HRESULT WINAPI rowset_info_GetReferencedRowset(IRowsetInfo *iface, DBORDINAL ordinal,
REFIID riid, IUnknown **unk)
{
ok(0, "Unexpected call\n");
return E_NOTIMPL;
}
static HRESULT WINAPI rowset_info_GetSpecification(IRowsetInfo *iface, REFIID riid,
IUnknown **specification)
{
ok(0, "Unexpected call\n");
return E_NOTIMPL;
}
static const struct IRowsetInfoVtbl rowset_info =
{
rowset_info_QueryInterface,
rowset_info_AddRef,
rowset_info_Release,
rowset_info_GetProperties,
rowset_info_GetReferencedRowset,
rowset_info_GetSpecification
};
static HRESULT WINAPI column_info_QueryInterface(IColumnsInfo *iface, REFIID riid, void **obj)
{
struct test_rowset *rowset = impl_from_IColumnsInfo( iface );
return IRowset_QueryInterface(&rowset->IRowset_iface, riid, obj);
}
static ULONG WINAPI column_info_AddRef(IColumnsInfo *iface)
{
struct test_rowset *rowset = impl_from_IColumnsInfo( iface );
return IRowset_AddRef(&rowset->IRowset_iface);
}
static ULONG WINAPI column_info_Release(IColumnsInfo *iface)
{
struct test_rowset *rowset = impl_from_IColumnsInfo( iface );
return IRowset_Release(&rowset->IRowset_iface);
}
static HRESULT WINAPI column_info_GetColumnInfo(IColumnsInfo *This, DBORDINAL *columns,
DBCOLUMNINFO **colinfo, OLECHAR **stringsbuffer)
{
DBCOLUMNINFO *dbcolumn;
*columns = 1;
*stringsbuffer = CoTaskMemAlloc(sizeof(L"Column1"));
lstrcpyW(*stringsbuffer, L"Column1");
dbcolumn = CoTaskMemAlloc(sizeof(DBCOLUMNINFO));
dbcolumn->pwszName = *stringsbuffer;
dbcolumn->pTypeInfo = NULL;
dbcolumn->iOrdinal = 1;
dbcolumn->dwFlags = DBCOLUMNFLAGS_MAYBENULL;
dbcolumn->ulColumnSize = 5;
dbcolumn->wType = DBTYPE_I4;
dbcolumn->bPrecision = 1;
dbcolumn->bScale = 1;
dbcolumn->columnid.eKind = DBKIND_NAME;
dbcolumn->columnid.uName.pwszName = *stringsbuffer;
*colinfo = dbcolumn;
return S_OK;
}
static HRESULT WINAPI column_info_MapColumnIDs(IColumnsInfo *This, DBORDINAL column_ids,
const DBID *dbids, DBORDINAL *columns)
{
ok(0, "Unexpected call\n");
return E_NOTIMPL;
}
static const struct IColumnsInfoVtbl column_info =
{
column_info_QueryInterface,
column_info_AddRef,
column_info_Release,
column_info_GetColumnInfo,
column_info_MapColumnIDs,
};
static HRESULT WINAPI rowset_QueryInterface(IRowset *iface, REFIID riid, void **obj)
{
struct test_rowset *rowset = impl_from_IRowset( iface );
*obj = NULL;
if (IsEqualIID(riid, &IID_IRowset) ||
IsEqualIID(riid, &IID_IUnknown))
{
trace("Requested interface IID_IRowset\n");
*obj = &rowset->IRowset_iface;
}
else if (IsEqualIID(riid, &IID_IRowsetInfo))
{
trace("Requested interface IID_IRowsetInfo\n");
*obj = &rowset->IRowsetInfo_iface;
}
else if (IsEqualIID(riid, &IID_IColumnsInfo))
{
trace("Requested interface IID_IColumnsInfo\n");
*obj = &rowset->IColumnsInfo_iface;
}
else if (IsEqualIID(riid, &IID_IRowsetLocate))
{
trace("Requested interface IID_IRowsetLocate\n");
return E_NOINTERFACE;
}
else if (IsEqualIID(riid, &IID_IDBAsynchStatus))
{
trace("Requested interface IID_IDBAsynchStatus\n");
return E_NOINTERFACE;
}
else if (IsEqualIID(riid, &IID_IAccessor))
{
trace("Requested interface IID_IAccessor\n");
return E_NOINTERFACE;
}
else if (IsEqualIID(riid, &UKN_INTERFACE))
{
trace("Unknown interface\n");
return E_NOINTERFACE;
}
if(*obj) {
IUnknown_AddRef((IUnknown*)*obj);
return S_OK;
}
ok(0, "Unsupported interface %s\n", wine_dbgstr_guid(riid));
return E_NOINTERFACE;
}
static ULONG WINAPI rowset_AddRef(IRowset *iface)
{
struct test_rowset *rowset = impl_from_IRowset( iface );
return InterlockedIncrement( &rowset->refs );
}
static ULONG WINAPI rowset_Release(IRowset *iface)
{
struct test_rowset *rowset = impl_from_IRowset( iface );
/* Object not allocated no need to destroy */
return InterlockedDecrement( &rowset->refs );
}
static HRESULT WINAPI rowset_AddRefRows(IRowset *iface, DBCOUNTITEM cRows, const HROW rghRows[],
DBREFCOUNT rgRefCounts[], DBROWSTATUS rgRowStatus[])
{
ok(0, "Unexpected call\n");
return E_NOTIMPL;
}
static HRESULT WINAPI rowset_GetData(IRowset *iface, HROW hRow, HACCESSOR hAccessor, void *pData)
{
ok(0, "Unexpected call\n");
return E_NOTIMPL;
}
static HRESULT WINAPI rowset_GetNextRows(IRowset *iface, HCHAPTER hReserved, DBROWOFFSET lRowsOffset,
DBROWCOUNT cRows, DBCOUNTITEM *pcRowObtained, HROW **prghRows)
{
ok(0, "Unexpected call\n");
return E_NOTIMPL;
}
static HRESULT WINAPI rowset_ReleaseRows(IRowset *iface, DBCOUNTITEM cRows, const HROW rghRows[],
DBROWOPTIONS rgRowOptions[], DBREFCOUNT rgRefCounts[], DBROWSTATUS rgRowStatus[])
{
ok(0, "Unexpected call\n");
return E_NOTIMPL;
}
static HRESULT WINAPI rowset_RestartPosition(IRowset *iface, HCHAPTER hReserved)
{
ok(0, "Unexpected call\n");
return E_NOTIMPL;
}
static const struct IRowsetVtbl rowset_vtbl =
{
rowset_QueryInterface,
rowset_AddRef,
rowset_Release,
rowset_AddRefRows,
rowset_GetData,
rowset_GetNextRows,
rowset_ReleaseRows,
rowset_RestartPosition
};
static ULONG get_refcount(void *iface)
{
IUnknown *unknown = iface;
IUnknown_AddRef(unknown);
return IUnknown_Release(unknown);
}
static void test_ADORecordsetConstruction(void)
{
_Recordset *recordset;
ADORecordsetConstruction *construct;
Fields *fields = NULL;
Field *field;
struct test_rowset testrowset;
IRowset *rowset;
HRESULT hr;
LONG ref, count;
hr = CoCreateInstance( &CLSID_Recordset, NULL, CLSCTX_INPROC_SERVER, &IID__Recordset, (void **)&recordset );
ok( hr == S_OK, "got %08x\n", hr );
hr = _Recordset_QueryInterface( recordset, &IID_ADORecordsetConstruction, (void**)&construct );
todo_wine ok( hr == S_OK, "got %08x\n", hr );
if (FAILED(hr))
{
goto done;
}
testrowset.IRowset_iface.lpVtbl = &rowset_vtbl;
testrowset.IRowsetInfo_iface.lpVtbl = &rowset_info;
testrowset.IColumnsInfo_iface.lpVtbl = &column_info;
testrowset.refs = 1;
rowset = &testrowset.IRowset_iface;
ref = get_refcount( rowset );
ok( ref == 1, "got %d\n", ref );
hr = ADORecordsetConstruction_put_Rowset( construct, (IUnknown*)rowset );
todo_wine ok( hr == S_OK, "got %08x\n", hr );
ref = get_refcount( rowset );
ok( ref == 2, "got %d\n", ref );
hr = _Recordset_get_Fields( recordset, &fields );
ok( hr == S_OK, "got %08x\n", hr );
ok( fields != NULL, "NULL value\n");
ref = get_refcount( rowset );
ok( ref == 2, "got %d\n", ref );
count = -1;
hr = Fields_get_Count( fields, &count );
ok( count == 1, "got %d\n", count );
if (count > 0)
{
VARIANT index;
LONG size;
DataTypeEnum type;
V_VT( &index ) = VT_BSTR;
V_BSTR( &index ) = SysAllocString( L"Column1" );
hr = Fields_get_Item( fields, index, &field );
ok( hr == S_OK, "got %08x\n", hr );
hr = Field_get_Type( field, &type );
ok( hr == S_OK, "got %08x\n", hr );
ok( type == adInteger, "got %d\n", type );
size = -1;
hr = Field_get_DefinedSize( field, &size );
ok( hr == S_OK, "got %08x\n", hr );
ok( size == 5, "got %d\n", size );
VariantClear(&index);
Field_Release(field);
}
ref = get_refcount(rowset);
ok( ref == 2, "got %d\n", ref );
Fields_Release(fields);
ADORecordsetConstruction_Release(construct);
done:
_Recordset_Release( recordset );
}
static void test_Fields(void)
{
_Recordset *recordset;
@ -1136,6 +1481,7 @@ START_TEST(msado15)
{
CoInitialize( NULL );
test_Connection();
test_ADORecordsetConstruction();
test_ConnectionPoint();
test_Fields();
test_Recordset();