Nikolay Sivov : oledb32: Implement IRowPosition_ClearRowPosition() with events.

Alexandre Julliard julliard at winehq.org
Fri Aug 23 13:49:34 CDT 2013


Module: wine
Branch: master
Commit: def652e594517d9307e1990504eaa211e0c213bb
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=def652e594517d9307e1990504eaa211e0c213bb

Author: Nikolay Sivov <nsivov at codeweavers.com>
Date:   Fri Aug 23 10:33:09 2013 +0400

oledb32: Implement IRowPosition_ClearRowPosition() with events.

---

 dlls/oledb32/rowpos.c         |   37 ++++++++++++++++++-
 dlls/oledb32/tests/database.c |   78 +++++++++++++++++++++++++++++++++++++++++
 include/dbs.idl               |   36 +++++++++++++++++++
 include/oledb.idl             |    2 -
 include/oledberr.h            |    1 +
 5 files changed, 150 insertions(+), 4 deletions(-)

diff --git a/dlls/oledb32/rowpos.c b/dlls/oledb32/rowpos.c
index d322a9d..a6c68b8 100644
--- a/dlls/oledb32/rowpos.c
+++ b/dlls/oledb32/rowpos.c
@@ -67,6 +67,22 @@ static inline rowpos_cp *impl_from_IConnectionPoint(IConnectionPoint *iface)
     return CONTAINING_RECORD(iface, rowpos_cp, IConnectionPoint_iface);
 }
 
+static HRESULT rowpos_fireevent(rowpos *rp, DBREASON reason, DBEVENTPHASE phase)
+{
+    HRESULT hr = S_OK;
+    DWORD i;
+
+    for (i = 0; i < rp->cp.sinks_size; i++)
+        if (rp->cp.sinks[i])
+        {
+            hr = IRowPositionChange_OnRowPositionChange(rp->cp.sinks[i], reason, phase, phase == DBEVENTPHASE_FAILEDTODO);
+            if (phase == DBEVENTPHASE_FAILEDTODO) return DB_E_CANCELED;
+            if (hr != S_OK) return hr;
+        }
+
+    return hr;
+}
+
 static HRESULT WINAPI rowpos_QueryInterface(IRowPosition* iface, REFIID riid, void **obj)
 {
     rowpos *This = impl_from_IRowPosition(iface);
@@ -122,8 +138,23 @@ static ULONG WINAPI rowpos_Release(IRowPosition* iface)
 static HRESULT WINAPI rowpos_ClearRowPosition(IRowPosition* iface)
 {
     rowpos *This = impl_from_IRowPosition(iface);
-    FIXME("(%p): stub\n", This);
-    return E_NOTIMPL;
+    HRESULT hr;
+
+    TRACE("(%p)\n", This);
+
+    if (!This->rowset) return E_UNEXPECTED;
+
+    hr = rowpos_fireevent(This, DBREASON_ROWPOSITION_CLEARED, DBEVENTPHASE_OKTODO);
+    if (hr != S_OK)
+        return rowpos_fireevent(This, DBREASON_ROWPOSITION_CLEARED, DBEVENTPHASE_FAILEDTODO);
+
+    hr = rowpos_fireevent(This, DBREASON_ROWPOSITION_CLEARED, DBEVENTPHASE_ABOUTTODO);
+    if (hr != S_OK)
+        return rowpos_fireevent(This, DBREASON_ROWPOSITION_CLEARED, DBEVENTPHASE_FAILEDTODO);
+
+    /* FIXME: actually clear stored data */
+
+    return S_OK;
 }
 
 static HRESULT WINAPI rowpos_GetRowPosition(IRowPosition *iface, HCHAPTER *chapter,
@@ -277,6 +308,8 @@ static HRESULT WINAPI rowpos_cp_Advise(IConnectionPoint *iface, IUnknown *unksin
 
     TRACE("(%p)->(%p %p)\n", This, unksink, cookie);
 
+    if (!cookie) return E_POINTER;
+
     hr = IUnknown_QueryInterface(unksink, &IID_IRowPositionChange, (void**)&sink);
     if (FAILED(hr))
     {
diff --git a/dlls/oledb32/tests/database.c b/dlls/oledb32/tests/database.c
index 585196c..f42f189 100644
--- a/dlls/oledb32/tests/database.c
+++ b/dlls/oledb32/tests/database.c
@@ -414,6 +414,83 @@ static void test_rowpos_initialize(void)
     IRowPosition_Release(rowpos);
 }
 
+static HRESULT WINAPI onchange_QI(IRowPositionChange *iface, REFIID riid, void **obj)
+{
+    if (IsEqualIID(riid, &IID_IUnknown) ||
+        IsEqualIID(riid, &IID_IRowPositionChange))
+    {
+        *obj = iface;
+        return S_OK;
+    }
+
+    return E_NOINTERFACE;
+}
+
+static ULONG WINAPI onchange_AddRef(IRowPositionChange *iface)
+{
+    return 2;
+}
+
+static ULONG WINAPI onchange_Release(IRowPositionChange *iface)
+{
+    return 1;
+}
+
+static HRESULT WINAPI onchange_OnRowPositionChange(IRowPositionChange *iface, DBREASON reason,
+    DBEVENTPHASE phase, BOOL cant_deny)
+{
+    trace("%d %d %d\n", reason, phase, cant_deny);
+    return S_OK;
+}
+
+static const IRowPositionChangeVtbl onchange_vtbl = {
+    onchange_QI,
+    onchange_AddRef,
+    onchange_Release,
+    onchange_OnRowPositionChange
+};
+
+static IRowPositionChange onchangesink = { &onchange_vtbl };
+
+static void init_onchange_sink(IRowPosition *rowpos)
+{
+    IConnectionPointContainer *cpc;
+    IConnectionPoint *cp;
+    DWORD cookie;
+    HRESULT hr;
+
+    hr = IRowPosition_QueryInterface(rowpos, &IID_IConnectionPointContainer, (void**)&cpc);
+    ok(hr == S_OK, "got %08x\n", hr);
+    hr = IConnectionPointContainer_FindConnectionPoint(cpc, &IID_IRowPositionChange, &cp);
+    ok(hr == S_OK, "got %08x\n", hr);
+    hr = IConnectionPoint_Advise(cp, (IUnknown*)&onchangesink, &cookie);
+    ok(hr == S_OK, "got %08x\n", hr);
+    IConnectionPoint_Release(cp);
+    IConnectionPointContainer_Release(cpc);
+}
+
+static void test_rowpos_clearrowposition(void)
+{
+    IRowPosition *rowpos;
+    HRESULT hr;
+
+    hr = CoCreateInstance(&CLSID_OLEDB_ROWPOSITIONLIBRARY, NULL, CLSCTX_INPROC_SERVER, &IID_IRowPosition, (void**)&rowpos);
+    ok(hr == S_OK, "got %08x\n", hr);
+
+    hr = IRowPosition_ClearRowPosition(rowpos);
+    ok(hr == E_UNEXPECTED, "got %08x\n", hr);
+
+    init_test_rset();
+    hr = IRowPosition_Initialize(rowpos, (IUnknown*)&test_rset.IRowset_iface);
+    ok(hr == S_OK, "got %08x\n", hr);
+
+    init_onchange_sink(rowpos);
+    hr = IRowPosition_ClearRowPosition(rowpos);
+    ok(hr == S_OK, "got %08x\n", hr);
+
+    IRowPosition_Release(rowpos);
+}
+
 START_TEST(database)
 {
     OleInitialize(NULL);
@@ -425,6 +502,7 @@ START_TEST(database)
     /* row position */
     test_rowposition();
     test_rowpos_initialize();
+    test_rowpos_clearrowposition();
 
     OleUninitialize();
 }
diff --git a/include/dbs.idl b/include/dbs.idl
index 46deb6a..ceb9773 100644
--- a/include/dbs.idl
+++ b/include/dbs.idl
@@ -686,3 +686,39 @@ typedef struct tagDBTIMESTAMP {
 	USHORT second;
 	ULONG fraction;
 } DBTIMESTAMP;
+
+typedef DWORD DBREASON;
+typedef DWORD DBEVENTPHASE;
+
+enum DBEVENTPHASEENUM {
+    DBEVENTPHASE_OKTODO,
+    DBEVENTPHASE_ABOUTTODO,
+    DBEVENTPHASE_SYNCHAFTER,
+    DBEVENTPHASE_FAILEDTODO,
+    DBEVENTPHASE_DIDEVENT
+};
+
+enum DBREASONENUM {
+    DBREASON_ROWSET_FETCHPOSITIONCHANGE,
+    DBREASON_ROWSET_RELEASE,
+    DBREASON_COLUMN_SET,
+    DBREASON_COLUMN_RECALCULATED,
+    DBREASON_ROW_ACTIVATE,
+    DBREASON_ROW_RELEASE,
+    DBREASON_ROW_DELETE,
+    DBREASON_ROW_FIRSTCHANCE,
+    DBREASON_ROW_INSERT,
+    DBREASON_ROW_RESYNCH,
+    DBREASON_ROW_UNDOCHANGE,
+    DBREASON_ROW_UNDOINSERT,
+    DBREASON_ROW_UNDODELETE,
+    DBREASON_ROW_UPDATE,
+    DBREASON_ROWSET_CHANGED
+};
+
+enum DBREASONENUM15 {
+    DBREASON_ROWPOSITION_CHANGED = DBREASON_ROWSET_CHANGED + 1,
+    DBREASON_ROWPOSITION_CHAPTERCHANGED,
+    DBREASON_ROWPOSITION_CLEARED,
+    DBREASON_ROW_ASYNCHINSERT
+};
diff --git a/include/oledb.idl b/include/oledb.idl
index 34cbd34..8d7f001 100644
--- a/include/oledb.idl
+++ b/include/oledb.idl
@@ -34,8 +34,6 @@ typedef LONG_PTR  DBROWCOUNT;
 typedef ULONG_PTR DBCOUNTITEM;
 typedef ULONG_PTR DBLENGTH;
 typedef ULONG_PTR DBORDINAL;
-typedef DWORD DBREASON;
-typedef DWORD DBEVENTPHASE;
 typedef ULONG_PTR DBBKMARK;
 typedef DWORD_PTR DB_DWRESERVE;
 typedef ULONG_PTR DBREFCOUNT;
diff --git a/include/oledberr.h b/include/oledberr.h
index c739d23..96adcae 100644
--- a/include/oledberr.h
+++ b/include/oledberr.h
@@ -63,6 +63,7 @@
 #define DB_E_BADACCESSORTYPE                0x80040e4b
 #define DB_E_WRITEONLYACCESSOR              0x80040e4c
 #define DB_SEC_E_AUTH_FAILED                0x80040e4d
+#define DB_E_CANCELED                       0x80040e4e
 
 #define DB_E_ALREADYINITIALIZED             0x80040e52
 #define DB_E_DATAOVERFLOW                   0x80040e57




More information about the wine-cvs mailing list