IRowsetRefresh::RefreshVisibleData

Retrieves the data values from the data source that are visible to the transaction for the specified rows.

HRESULT RefreshVisibleData (
HCHAPTER          hChapter,
ULONG             cRows,
const HROW       rghRows[],
BOOL                fOverwrite,
ULONG*            pcRowsRefreshed,
HROW**            prghRowsRefreshed,
DBROWSTATUS**     prgRowStatus);

Parameters

hChapter

[in]
The chapter handle. For nonchaptered rowsets, hChapter is ignored.

cRows

[in]
The count of rows to refresh. If cRows is zero, RefreshVisibleData ignores rghRows and reads in current values for all active rows.

rghRows

[in]
An array of cRows row handles to be refreshed. If cRows is zero, this argument is ignored.

fOverwrite

[in]
TRUE if the provider should discard any pending changes to a given row and accept the visible values as the new current values; FALSE otherwise.

pcRowsRefreshed

[out]
A pointer to memory in which to return the number of rows the method attempted to refresh. If this is a null pointer, no count of rows is returned. If an error occurs, the provider sets *pcRowsRefreshed to zero.

prghRowsRefreshed

[out]
A pointer to memory in which to return the array of row handles the method attempted to refresh. If cRows is not zero, then the elements of this array are in one-to-one correspondence with those of rghRows. If cRows is zero, the elements of this array are the handles of all active rows with pending changes in the chapter, or all active rows with pending changes in the rowset if hChapter is DB_NULL_HCHAPTER. When cRows is zero, RefreshVisibleData will add to the reference count of the rows whose handles are returned in prghRowsRefreshed.

The rowset allocates memory for the handles and the client should release this memory with IMalloc::Free when no longer needed. This argument is ignored if pcRowsRefreshed is a null pointer and must not be a null pointer otherwise. If *pcRowsRefreshed is zero on output or the method fails, the provider does not allocate any memory and ensures that *prghRowsRefreshed is a null pointer on output.

prgRowStatus

[out]
A pointer to memory in which to return an array of row status values. The elements of this array correspond one-to-one with the elements of *prghRowsRefreshed. If no errors occur while refreshing a row, the corresponding element of *prgRowStatus is set to DBROWSTATUS_S_OK if the row is successfully resynchronized, or DBROWSTATUS_S_NOCHANGE if the provider can easily determine that there was no change to the value. If an error occurs while refreshing a row, the corresponding element is set as specified in DB_S_ERRORSOCCURRED. If prgRowStatus is a null pointer, no row status values are returned.

The rowset allocates memory for the row status values and returns the address to this memory; the client releases this memory with IMalloc::Free when it is no longer needed. This argument is ignored if pcRowsRefreshed is a null pointer. If *pcRowsRefreshed is zero on output or the method fails, the provider does not allocate any memory and ensures that *prgRowStatus is a null pointer on output.

Return Code

S_OK

The method succeeded. All rows were successfully processed. For each row, prgRowStatus contains one of the following:

DB_S_ERRORSOCCURRED

An error occurred while refreshing a row, but at least one row was successfully refreshed. Successes can occur for the reason listed under S_OK. The following errors can occur:

E_FAIL

A provider-specific error occurred.

E_INVALIDARG

cRows was not zero and rghRows was a null pointer.

pcRowsRefreshed was not a null pointer and prghRowsRefreshed was a null pointer.

E_UNEXPECTED

ITransaction::Commit or ITransaction::Abort was called and the object is in a zombie state.

DB_E_ERRORSOCCURRED

Errors occurred while refreshing all of the rows. Errors can occur for the reasons listed under DB_S_ERRORSOCCURRED.

DB_E_NOTREENTRANT

The provider called a method from IRowsetNotify in the consumer and the method has not yet returned.

DB_SEC_E_PERMISSIONDENIED

The consumer did not have sufficient permission to refresh the rows.

Comments

RefreshVisibleData retrieves the data values from the data source that are visible to the transaction for the specified rows. Changes made to the row by the current transaction are always visible to RefreshVisibleData, including changes made by other rowsets in the same transaction. Whether changes made by other transactions are visible to RefreshVisibleData depends on the isolation level of the current transaction. Thus, RefreshVisibleData uses values as follows:

For providers that keep a local copy of visible data, RefreshVisibleData updates the provider's local copy of the visible data for any indicated rows with pending changes.

When fOverwrite is TRUE, the provider discards any pending changes to a given row and accepts the visible values as the new current values that will be returned by calling GetData or GetOriginalData. This affects rows with or without pending changes. Any changes already transmitted to the data source are not lost; they will be committed or aborted when the transaction is committed or aborted. But all pending changes are lost because they exist only in the rowset’s copy of the row and the fOverwrite TRUE option overwrites the contents of this copy. The pending change status in this case is removed from the row.

When fOverwrite is FALSE, the provider makes no change to the pending status of the row. It does not affect the current values of the row (available through IRowset::GetData) or the original values of the row (available through IRowsetUpdate::GetOriginalData). If the provider keeps a local copy of the visible data values, it refreshes the values for the indicated rows. If the provider does not keep a local copy of the visible data values, the indicated row has no pending changes, or all columns in the row are deferred, the provider reports success without taking any action.

Providers that perform optimistic updates in a disconnected scenario usually use the cached visible values on a pending row as the source of concurrency conflict detection values. For example, the values used to identify the row to a SQL-based provider through a WHERE clause would come from this buffer. Thus, refreshing the visible values buffer for a row with pending changes via RefreshVisibleData potentially affects the behavior of a subsequent call to IRowsetUpdate::Update for that row because it may introduce new acceptable identity values into the conflict-detection mechanism of the provider.

If a specified row has been deleted from the data source and this deletion is visible, RefreshVisibleData returns DBROWSTATUS_E_DELETED in the error status array for the row. This row is subsequently treated as a deleted row for the purposes of IRowset::GetData (if fOverwrite is TRUE) or for GetLastVisibleData (if fOverwrite is FALSE).

If RefreshVisibleData encounters an error while attempting to refresh a row, such as a bad row handle, it notes the error in *prgRowStatus, continues processing, and returns DB_S_ERRORSOCCURRED or DB_E_ERRORSOCCURRED. Although the rows are refreshed in undefined order, the ordering of *prgRowStatus must match the order of the row handle array, so the consumer can perform a side-by-side scan of each array to determine which rows were not refreshed.

If cRows is zero and pcRowsRefreshed and prghRowsRefreshed are not null pointers, RefreshVisibleData adds to the reference count of the rows it returns in *prghRowsRefreshed to ensure that the consumer has these row handles.

See Also

IRowsetRefresh::GetLastVisibleData