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