IRowsetNotify

OLE DB Programmer's Reference

IRowsetNotify is the callback interface that a consumer must support to connect to local notifications provided by a rowset object. The notifications are intended to synchronize objects that are attached to the same rowset instance. The notifications do not reflect changes in underlying shared tables that occur through other programs or users.

The notifications use the standard COM connection point scheme for operations or events on rowset objects. A rowset object supports IConnectionPointContainer, and the consumer calls FindConnectionPoint for IID_IRowsetNotify to obtain the correct IConnectionPoint interface. The consumer then advises that connection point to connect and supplies a pointer to the consumer's IRowsetNotify interface.

Providers are required to support all notifications for which they have the underlying functionality.

For more information about notifications, see Chapter 12: OLE DB Object Notifications.

When to Implement

IRowsetNotify is implemented by consumers that require notification. If the command requests support for IConnectionPointContainer, the rowset object is required to support a connection point for IRowsetNotify. Providers should implement this connection point if they expect to work directly with general-purpose consumers.

Notification about transactions is not handled through rowset objects. There may be multiple rowsets for each transaction, leading to a flood of events. Consumers that need to be notified of transaction activity should connect to the transaction coordinator. For more information, see "Event Notifications" in Chapter 15: Transactions.

IRowset is a prerequisite for notification.

DBEVENTPHASE

Notifications have multiple phases. The provider uses the IRowsetNotify callback method for every phase of the notification. A phase describes the state of the notification as the provider and consumer signal intent, approval, rejection, or completion of the change. The phases are similar to phases in a two-phase transaction commit protocol because the problem of ensuring that all controls authorize and succeed in handling a event or action on a rowset is very similar to the problem of ensuring that all resource managers agree to, and succeed in, committing a transaction.

In OLE DB, phases are enumerated by DBEVENTPHASE values, as listed in the following table. In the descriptions, all consumer objects that connect their IRowsetNotify interface to the rowset object are the listeners.

Value Description
DBEVENTPHASE_OKTODO Informs a listener of an impending event. All listeners must return S_OK from DBEVENTPHASE_OKTODO for the event to proceed. Any listener can cancel the impending event (DBREASON) by returning S_FALSE. The listener can prepare for the event but should do nothing irreversible or time consuming.

If a listener cancels the event (DBREASON), all listeners that have already been called will be called again with DBEVENTPHASE_FAILEDTODO.

DBEVENTPHASE_ABOUTTODO Informs a listener that DBEVENTPHASE_OKTODO has been approved and that all listeners can proceed to final preparations, which must be reversible but which may be lengthy. The listener should cancel this phase only if it is stopped by an error; it should have cleared all logical objections at the earlier DBEVENTPHASE_OKTODO phase.

If a listener cancels the event by returning S_FALSE, all listeners that have already been called will be called again with DBEVENTPHASE_FAILEDTODO.

DBEVENTPHASE_SYNCHAFTER Informs a listener that the event has occurred after the rowset object's copy of the row has been modified but before the data store has received the change. The listener can synchronize itself with the rowset and ensure that it has no physical reason not to agree to commit the changes.

If a listener cancels the event (DBREASON) by returning S_FALSE, all listeners that have already been called will be called again with DBEVENTPHASE_FAILEDTODO.

DBEVENTPHASE_FAILEDTODO Informs a listener that has previously been called for this event that the action on the rowset object has failed. The listener should reverse all changes and synchronize with the state of the rowset.
DBEVENTPHASE_DIDEVENT Informs a listener that all consumers have synchronized themselves and agreed to commit the changes. The listener should now commit its changes.

The final phase of a notification is always either DBEVENTPHASE_FAILEDTODO or DBEVENTPHASE_DIDEVENT. If there are no phases, it is equivalent to DBEVENTPHASE_DIDEVENT.

All providers must support the DBEVENTPHASE_FAILEDTODO and DBEVENTPHASE_DIDEVENT phases. Whether providers support DBEVENTPHASE_OKTODO, DBEVENTPHASE_ABOUTTODO, and DBEVENTPHASE_SYNCHAFTER is provider specific, although all but the simplest providers support these phases. To determine which phases a provider supports, a consumer calls IDBProperties::GetProperties for the DBPROP_NOTIFICATIONPHASES property.

If a method changes multiple rows and generates one notification for the phase, such as DBREASON_ROW_ACTIVATE or DBREASON_ROW_RELEASE, the provider makes a single call to IRowsetNotify::OnRowChange and passes an array containing the handles of all of the affected rows.

If a method changes multiple rows and generates multiple notifications, such as DBREASON_ROW_UPDATE or DBREASON_ROW_UNDOCHANGE, the number of calls to IRowsetNotify::OnRowChange for each phase depends on the DBPROP_NOTIFICATIONGRANULARITY property.

It is provider-specific whether or not listeners who register after some but not all of the phases of an event have been fired are called for the remaining phases. A listener must be prepared to get only the final phases of an event when registering for notifications on an object that is in the midst of sending notifications.

DBREASON

Reasons are types of events or "fine-tunings" of the notifications generated by events on rowset objects. The receiver of notifications is expected to care only about the general effect of the event, but there may be other effects that more specialized consumers need to know about. The DBEVENTPHASE represents the basic state of the event, and the DBREASON is a reason for the event.

Providers are required to support all DBREASONs for which they have the underlying functionality. IRowsetNotify methods must return S_OK or DB_S_UNWANTEDREASON when they receive a DBREASON value they do not recognize. Providers are not expected to add new DBREASONs to the defined set. Providers defining new DBREASONs should do so through an entirely new notification interface with its own IID.

The values described in the following table are valid for DBREASON.

Value Description
DBREASON_ROW_ASYNCHINSERT The rowset is being randomly asynchronously populated, and one or more rows have been inserted. Only the DBEVENTPHASE_DIDEVENT phase occurs.

For more information, see "Asynchronous Rowset Population" in Chapter 17: Asynchronous Processing.

DBREASON_ROWSET_FETCHPOSITIONCHANGE The next fetch position changed as a result of a call to IRowset::GetNextRows or IRowset::RestartPosition. All phases can occur.
DBREASON_ROWSET_RELEASE The rowset is being released; that is, its reference count is zero. Only the DBEVENTPHASE_DIDEVENT phase occurs. The rowset no longer exists when the notification for this DBREASON is sent out, so recipients must not make any calls upon it. In COM, there is no way to deny permission to IUnknown::Release.
DBREASON_ROWSET_CHANGED The rowset metadata has changed.

Pointers to interfaces on the rowset remain valid.

Providers must revalidate accessors against the metadata, and this might fail due to the changes in the metadata. For example, the accessor might now specify an unsupported conversion.

Consumers should free any held row handles when a notification with this DBREASON is generated, because handles to rows are likely to have become invalid. For example, IRowset::GetData might return DB_E_BADROWHANDLE, or IRowsetUpdate::Update might return DBROWSTATUS_E_INVALID. The result of passing such a row handle is provider-specific, although the provider cannot terminate abnormally.

Only the DBEVENTPHASE_DIDEVENT phase occurs.

DBREASON_COLUMN_SET A column value is set. All phases can occur.
DBREASON_COLUMN_RECALCULATED A calculated column takes a new value because its input columns change. Only the DBEVENTPHASE_DIDEVENT phase occurs.
DBREASON_ROW_ACTIVATE A function, such as IRowset::GetNextRows or IRowsetLocate::GetRowsAt, caused a new set of rows to be fetched. Only the DBEVENTPHASE_DIDEVENT phase occurs. For best results, the provider should send this reason for newly fetched rows only, but it might be expensive for providers to determine whether or not a row is newly fetched.
DBREASON_ROW_RELEASE IRowset::ReleaseRows was called, and the row's reference count is zero. The array of row handles the provider passed to the listeners is the subset of the original array of row handles passed to ReleaseRows—that is, those row handles for which the reference count is zero. Only the DBEVENTPHASE_DIDEVENT phase occurs. The returned row handles might be invalid and therefore should not be used with any methods.
DBREASON_ROW_DELETE IRowsetChange::DeleteRows has been called. All phases can occur.
DBREASON_ROW_FIRSTCHANGE The first time any column in the row is set, this notification occurs. It precedes DBREASON_COLUMN_SET. All phases can occur. This reason occurs only when the rowset is in delayed update mode. It occurs the first time a column in a row is modified after the row was fetched or after the last call to IRowsetUpdate::Update or IRowsetUpdate::Undo, whichever is more recent.
DBREASON_ROW_INSERT IRowsetChange::InsertRow has been called. All phases can occur.
DBREASON_ROW_RESYNCH IRowsetRefresh::RefreshVisibleData has been called. All phases can occur.
DBREASON_ROW_UNDOCHANGE IRowsetUpdate::Undo has been called on a pending change row. All phases can occur.
DBREASON_ROW_UNDOINSERT IRowsetUpdate::Undo has been called on a pending insert row. All phases can occur.
DBREASON_ROW_UNDODELETE IRowsetUpdate::Undo has been called on a pending delete row. All phases can occur.
DBREASON_ROW_UPDATE IRowsetUpdate::Update has been called on a row with a pending change. All phases can occur.

The following table lists all rowset methods, the DBREASON values they generate, and the phases for each reason. Nested notifications occur when the consumer calls another rowset method while processing a notification.

Method DBREASON generated [1] Phases
IUnknown::AddRef None N/A
IUnknown::QueryInterface None N/A
IUnknown::Release _ROWSET_RELEASE DIDEVENT
ICommand::Execute _ROW_ASYNCINSERT [2] DIDEVENT
IOpenRowset::OpenRowset _ROW_ASYNCINSERT [2] DIDEVENT
IRowset::AddRefRows None N/A
IRowset::GetData None N/A
IRowset::GetNextRows _ROW_ACTIVATE DIDEVENT
  _ROWSET_FETCHPOSITIONCHANGE All Phases
IRowset::ReleaseRows _ROW_RELEASE DIDEVENT
IRowset::RestartPosition _ROWSET_FETCHPOSITIONCHANGE All Phases
  _ROWSET_CHANGED [3] All Phases
IRowsetChange::DeleteRows _ROW_DELETE All Phases
IRowsetChange::InsertRow _ROW_INSERT All Phases
IRowsetChange::SetData _ROW_FIRSTCHANGE [4] All Phases
  _COLUMN_SET All Phases
  _COLUMN_RECALCULATED DIDEVENT
IRowsetIndex::Seek _ROWSET_FETCHPOSITIONCHANGE All Phases
IRowsetLocate::Compare None N/A
IRowsetLocate::GetRowsAt _ROW_ACTIVATE DIDEVENT
IRowsetLocate::GetRowsByBookmark _ROW_ACTIVATE DIDEVENT
IRowsetLocate::Hash None N/A
IRowsetRefresh::GetLastVisibleData None N/A
IRowsetRefresh::RefreshVisibleData _ROW_RESYNCH All Phases
IRowsetScroll::GetApproximatePosition None N/A
IRowsetScroll::GetRowsAtRatio _ROW_ACTIVATE DIDEVENT
IRowsetUpdate::GetOriginalData None N/A
IRowsetUpdate::GetPendingRows None N/A
IRowsetUpdate::Undo _ROW_UNDOCHANGE All Phases
  _ROW_UNDOINSERT All Phases
  _ROW_UNDODELETE All Phases
IRowsetUpdate::Update _ROW_UPDATE All Phases
All other rowset methods None N/A

[1]   Methods generate only the listed DBREASON values, even though other reasons might seem appropriate. For example, IRowsetChange::InsertRow generates only DBREASON_ROW_INSERT even though DBREASON_COLUMN_SET, DBREASON_ROW_FIRSTCHANGE, and DBREASON_ROW_ACTIVATE might appear to be applicable.

[2]   ICommand::Execute and IOpenRowset::OpenRowset generate this DBREASON only when the rowsets are being populated asynchronously.

[3]   IRowset::RestartPosition generates this DBREASON only when the metadata for the columns has changed.

[4]   DBREASON_ROW_FIRSTCHANGE is generated only the first time a column in the row is changed. For more information, see the table of DBREASON values earlier in this section.

Method Description
OnFieldChange Notifies the consumer of any change to the value of a column.
OnRowChange Notifies the consumer of the first change to a row or of any change that affects the entire row.
OnRowsetChange Notifies the consumer of any change affecting the entire rowset.

1998-2001 Microsoft Corporation. All rights reserved.



Microsoft Ole Db 2.0 Programmer's Reference and Data Access SDK
Microsoft OLE DB 2.0 Programmers Reference and Data Access SDK (Microsoft Professional Editions)
ISBN: 0735605904
EAN: 2147483647
Year: 1998
Pages: 1083

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net