[prev in list] [next in list] [prev in thread] [next in thread] 

List:       wine-devel
Subject:    [PATCH 5/5] msdasql: Return valid object from ICommandText Execute.
From:       Alistair Leslie-Hughes <leslie_alistair () hotmail ! com>
Date:       2021-10-31 8:51:18
Message-ID: PU4P216MB1255AA5568614972E071811993899 () PU4P216MB1255 ! KORP216 ! PROD ! OUTLOOK ! COM
[Download RAW message or body]

Until we query ODBC, we aren't able workout if we need a recordset
or not.  As a start, always return an interface, this way we can
add the required interface for a rowset.

Signed-off-by: Alistair Leslie-Hughes <leslie_alistair@hotmail.com>
---
 dlls/msdasql/session.c        | 127 +++++++++++++++++++++++++++++++++-
 dlls/msdasql/tests/provider.c |  41 +++++++++++
 2 files changed, 166 insertions(+), 2 deletions(-)

diff --git a/dlls/msdasql/session.c b/dlls/msdasql/session.c
index 8b96620cc41..61be9e8505f 100644
--- a/dlls/msdasql/session.c
+++ b/dlls/msdasql/session.c
@@ -409,12 +409,135 @@ static HRESULT WINAPI command_Cancel(ICommandText *iface)
     return E_NOTIMPL;
 }
 
+struct msdasql_rowset
+{
+    IRowset IRowset_iface;
+    LONG refs;
+};
+
+static inline struct msdasql_rowset *impl_from_IRowset( IRowset *iface )
+{
+    return CONTAINING_RECORD( iface, struct msdasql_rowset, IRowset_iface );
+}
+
+static HRESULT WINAPI msdasql_rowset_QueryInterface(IRowset *iface, REFIID riid,  \
void **ppv) +{
+    struct msdasql_rowset *rowset = impl_from_IRowset( iface );
+
+    TRACE( "%p, %s, %p\n", rowset, debugstr_guid(riid), ppv );
+
+    *ppv = NULL;
+    if(IsEqualGUID(&IID_IUnknown, riid) ||
+       IsEqualGUID(&IID_IRowset, riid))
+    {
+        *ppv = &rowset->IRowset_iface;
+    }
+
+    if(*ppv)
+    {
+        IUnknown_AddRef((IUnknown*)*ppv);
+        return S_OK;
+    }
+
+    FIXME("(%p)->(%s %p)\n", iface, debugstr_guid(riid), ppv);
+    return E_NOINTERFACE;
+}
+
+static ULONG WINAPI msdasql_rowset_AddRef(IRowset *iface)
+{
+    struct msdasql_rowset *rowset = impl_from_IRowset( iface );
+    LONG refs = InterlockedIncrement( &rowset->refs );
+    TRACE( "%p new refcount %d\n", rowset, refs );
+    return refs;
+}
+
+static ULONG WINAPI msdasql_rowset_Release(IRowset *iface)
+{
+    struct msdasql_rowset *rowset = impl_from_IRowset( iface );
+    LONG refs = InterlockedDecrement( &rowset->refs );
+    TRACE( "%p new refcount %d\n", rowset, refs );
+    if (!refs)
+    {
+        TRACE( "destroying %p\n", rowset );
+        heap_free( rowset );
+    }
+    return refs;
+}
+
+static HRESULT WINAPI msdasql_rowset_AddRefRows(IRowset *iface, DBCOUNTITEM count,
+        const HROW rows[], DBREFCOUNT ref_counts[], DBROWSTATUS status[])
+{
+    struct msdasql_rowset *rowset = impl_from_IRowset( iface );
+    FIXME("%p, %ld, %p, %p, %p\n", rowset, count, rows, ref_counts, status);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI msdasql_rowset_GetData(IRowset *iface, HROW row, HACCESSOR \
accessor, void *data) +{
+    struct msdasql_rowset *rowset = impl_from_IRowset( iface );
+    FIXME("%p, %ld, %ld, %p\n", rowset, row, accessor, data);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI msdasql_rowset_GetNextRows(IRowset *iface, HCHAPTER reserved, \
DBROWOFFSET offset, +        DBROWCOUNT count, DBCOUNTITEM *obtained, HROW **rows)
+{
+    struct msdasql_rowset *rowset = impl_from_IRowset( iface );
+    FIXME("%p, %ld, %ld, %ld, %p, %p\n", rowset, reserved, offset, count, obtained, \
rows); +    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI msdasql_rowset_ReleaseRows(IRowset *iface, DBCOUNTITEM count,
+        const HROW rows[], DBROWOPTIONS options[], DBREFCOUNT ref_counts[], \
DBROWSTATUS status[]) +{
+    struct msdasql_rowset *rowset = impl_from_IRowset( iface );
+
+    FIXME("%p, %ld, %p, %p, %p, %p\n", rowset, count, rows, options, ref_counts, \
status); +    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI msdasql_rowset_RestartPosition(IRowset *iface, HCHAPTER \
reserved) +{
+    struct msdasql_rowset *rowset = impl_from_IRowset( iface );
+    FIXME("%p, %ld\n", rowset, reserved);
+    return E_NOTIMPL;
+}
+
+static const struct IRowsetVtbl msdasql_rowset_vtbl =
+{
+    msdasql_rowset_QueryInterface,
+    msdasql_rowset_AddRef,
+    msdasql_rowset_Release,
+    msdasql_rowset_AddRefRows,
+    msdasql_rowset_GetData,
+    msdasql_rowset_GetNextRows,
+    msdasql_rowset_ReleaseRows,
+    msdasql_rowset_RestartPosition
+};
+
 static HRESULT WINAPI command_Execute(ICommandText *iface, IUnknown *outer, REFIID \
riid,  DBPARAMS *params, DBROWCOUNT *affected, IUnknown **rowset)
 {
     struct command *command = impl_from_ICommandText( iface );
-    FIXME("%p, %p, %s, %p %p %p\n", command, outer, debugstr_guid(riid), params, \
                affected, rowset);
-    return E_NOTIMPL;
+    struct msdasql_rowset *msrowset;
+    HRESULT hr;
+
+    FIXME("%p, %p, %s, %p %p %p Semi Stub\n", command, outer, debugstr_guid(riid), \
params, affected, rowset); +
+    msrowset = heap_alloc(sizeof(*msrowset));
+    if (!msrowset)
+        return E_OUTOFMEMORY;
+
+    msrowset->IRowset_iface.lpVtbl = &msdasql_rowset_vtbl;
+    msrowset->refs = 1;
+
+    if (affected)
+        *affected = 0; /* FIXME */
+
+    hr = IRowset_QueryInterface(&msrowset->IRowset_iface, riid, (void**)rowset);
+    IRowset_Release(&msrowset->IRowset_iface);
+
+    return hr;
 }
 
 static HRESULT WINAPI command_GetDBSession(ICommandText *iface, REFIID riid, \
                IUnknown **session)
diff --git a/dlls/msdasql/tests/provider.c b/dlls/msdasql/tests/provider.c
index 35dfeb10d3d..df642a6a637 100644
--- a/dlls/msdasql/tests/provider.c
+++ b/dlls/msdasql/tests/provider.c
@@ -222,6 +222,46 @@ static void test_command_dbsession(IUnknown *cmd, IUnknown \
*session)  ICommandText_Release(comand_text);
 }
 
+static void test_command_rowset(IUnknown *cmd)
+{
+    ICommandText *comand_text;
+    HRESULT hr;
+    IUnknown *unk = NULL;
+    IRowset *rowset;
+    DBROWCOUNT affected;
+
+    hr = IUnknown_QueryInterface(cmd, &IID_ICommandText, (void**)&comand_text);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+
+    hr = ICommandText_SetCommandText(comand_text, &DBGUID_DEFAULT, L"CREATE TABLE \
testing (col1 INT, col2 SHORT)"); +    ok(hr == S_OK, "got 0x%08x\n", hr);
+
+    affected = 9999;
+    hr = ICommandText_Execute(comand_text, NULL, &IID_IRowset, NULL, &affected, \
&unk); +    ok(hr == S_OK, "got 0x%08x\n", hr);
+    todo_wine ok(unk == NULL, "Unexepcted value\n");
+    todo_wine ok(affected == -1, "got %ld\n", affected);
+    if (unk)
+        IUnknown_Release(unk);
+
+    affected = 9999;
+    hr = ICommandText_SetCommandText(comand_text, &DBGUID_DEFAULT, L"select * from \
testing"); +    ok(hr == S_OK, "got 0x%08x\n", hr);
+    if (hr == S_OK && unk)
+    {
+        ok(affected == 0, "wrong affected value\n");
+
+        hr = IUnknown_QueryInterface(unk, &IID_IRowset, (void**)&rowset);
+        ok(hr == S_OK, "got 0x%08x\n", hr);
+
+        IRowset_Release(rowset);
+        IUnknown_Release(unk);
+    }
+
+    ICommandText_Release(comand_text);
+}
+
+
 static void test_sessions(void)
 {
     IDBProperties *props;
@@ -298,6 +338,7 @@ static void test_sessions(void)
         test_command_interfaces(cmd);
         test_command_text(cmd);
         test_command_dbsession(cmd, session);
+        test_command_rowset(cmd);
         IUnknown_Release(cmd);
     }
 
-- 
2.33.0


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic