📄 ifrowsetimpl.h
字号:
// Note, status should be set by SetDBStatus bFailed = true; } else { __if_exists(T::Fire_OnFieldChange) { if (/* pRow->m_status != DBPENDINGSTATUS_NEW && */ pRow->m_status != (DBPENDINGSTATUS_NEW | DBPENDINGSTATUS_UNCHANGED)) { pT->Fire_OnFieldChange(pT, hNotifyRow, pBinding->cBindings, rgColumns.GetData(), DBREASON_COLUMN_SET, DBEVENTPHASE_DIDEVENT, TRUE); } } bSucceeded = true; } continue; break; } case DBSTATUS_S_OK: // Still call SetDBStatus here as they may have locks on // integrity contstraints to observe if (FAILED(pT->SetDBStatus(&dbStat, pRow, pColCur))) { __if_exists(T::Fire_OnFieldChange) { if (/* pRow->m_status != DBPENDINGSTATUS_NEW && */ pRow->m_status != (DBPENDINGSTATUS_NEW | DBPENDINGSTATUS_UNCHANGED)) { pT->Fire_OnFieldChange(pT, hNotifyRow, pBinding->cBindings, rgColumns.GetData(), DBREASON_COLUMN_SET, DBEVENTPHASE_FAILEDTODO, TRUE); } } bFailed = true; *((DBSTATUS*)((BYTE*)(pSrcData) + pBindCur->obStatus)) = dbStat; continue; } break; default: *((DBSTATUS*)((BYTE*)(pSrcData) + pBindCur->obStatus)) = DBSTATUS_E_BADSTATUS; __if_exists(T::Fire_OnFieldChange) { if (/* pRow->m_status != DBPENDINGSTATUS_NEW && */ pRow->m_status != (DBPENDINGSTATUS_NEW | DBPENDINGSTATUS_UNCHANGED)) { pT->Fire_OnFieldChange(pT, hNotifyRow, pBinding->cBindings, rgColumns.GetData(), DBREASON_COLUMN_SET, DBEVENTPHASE_FAILEDTODO, TRUE); } } bFailed = true; continue; break; } } } // Determine sizes of input and output columns DBLENGTH cbCol = 0; DBLENGTH cbDst; if (bReading) cbDst = pBindCur->cbMaxLen; else cbDst = pColCur->ulColumnSize; switch (pColCur->wType) { case DBTYPE_STR: if (bReading) cbCol = lstrlenA((LPSTR)(((BYTE*)pSrcData) + pColCur->cbOffset)); else { // Use the length field when setting data if (pBindCur->dwPart & DBPART_LENGTH) cbCol = *((DBLENGTH*)((BYTE*)(pSrcData) + pBindCur->obLength)); else cbCol = lstrlenA((LPSTR)(pSrcTemp)); // was cbDst if (cbCol >= cbDst) { if (cbCol > (cbDst + 1)) // over maximum case { __if_exists(T::Fire_OnFieldChange) { if (/* pRow->m_status != DBPENDINGSTATUS_NEW && */ pRow->m_status != (DBPENDINGSTATUS_NEW | DBPENDINGSTATUS_UNCHANGED)) { pT->Fire_OnFieldChange(pT, hNotifyRow, pBinding->cBindings, rgColumns.GetData(), DBREASON_COLUMN_SET, DBEVENTPHASE_FAILEDTODO, TRUE); } } bFailed = true; if (pBindCur->dwPart & DBPART_STATUS) *((DBSTATUS*)((BYTE*)(pSrcData) + pBindCur->obStatus)) = DBSTATUS_E_CANTCONVERTVALUE; continue; } } cbCol = cbDst; // Leave room for NULL term. need to copy for WSTR } break; case DBTYPE_WSTR: case DBTYPE_BSTR: if (bReading) cbCol = lstrlenW((LPWSTR)(((BYTE*)pSrcData) + pColCur->cbOffset)) * sizeof(WCHAR); else { if (pBindCur->dwPart & DBPART_LENGTH) cbCol = *((DBLENGTH*)((BYTE*)(pSrcData) + pBindCur->obLength)); else cbCol = lstrlenW((LPWSTR)(pSrcData)) * sizeof(WCHAR); if (cbCol >= cbDst) { if (cbCol > (cbDst + 1)) // over maximum case { __if_exists(T::Fire_OnFieldChange) { if (/* pRow->m_status != DBPENDINGSTATUS_NEW && */ pRow->m_status != (DBPENDINGSTATUS_NEW | DBPENDINGSTATUS_UNCHANGED)) { pT->Fire_OnFieldChange(pT, hNotifyRow, pBinding->cBindings, rgColumns.GetData(), DBREASON_COLUMN_SET, DBEVENTPHASE_FAILEDTODO, TRUE); } } bFailed = true; if (pBindCur->dwPart & DBPART_STATUS) *((DBSTATUS*)((BYTE*)(pSrcData) + pBindCur->obStatus)) = DBSTATUS_E_CANTCONVERTVALUE; continue; } } cbCol = cbDst; // Leave room for NULL term. need to copy for WSTR } break; case DBTYPE_BYTES: if (bReading) cbCol = pColCur->ulColumnSize; else { if (pBindCur->dwPart & DBPART_LENGTH) cbCol = *((DBLENGTH *)((BYTE*)(pSrcData) + pBindCur->obLength)); else { __if_exists(T::Fire_OnFieldChange) { if (/* pRow->m_status != DBPENDINGSTATUS_NEW && */ pRow->m_status != (DBPENDINGSTATUS_NEW | DBPENDINGSTATUS_UNCHANGED)) { pT->Fire_OnFieldChange(pT, hNotifyRow, pBinding->cBindings, rgColumns.GetData(), DBREASON_COLUMN_SET, DBEVENTPHASE_FAILEDTODO, TRUE); } } // If no length part is bound for DBTYPE_BYTES, it is an error bFailed = true; continue; } if (cbCol >= cbDst) cbCol = cbDst; // Leave room for NULL term. need to copy for WSTR } break; default: if (bReading) cbCol = pColCur->ulColumnSize; else cbDst = pColCur->ulColumnSize; break; } // Handle cases where we have provider owned memory. Note, these should be // with DBTYPE_BYREF (otherwise, it doesn't make sense). if (pBindCur->dwPart & DBPART_VALUE) { if (pBindCur->dwMemOwner == DBMEMOWNER_PROVIDEROWNED && pBindCur->wType & DBTYPE_BYREF) { *(BYTE**)pDstTemp = pSrcTemp; } else { ATLASSERT(pT->m_spConvert != NULL); hr = pT->m_spConvert->DataConvert(pColCur->wType, pBindCur->wType, cbCol, &cbDst, pSrcTemp, pDstTemp, pBindCur->cbMaxLen, dbStat, &dbStat, pBindCur->bPrecision, pBindCur->bScale,0); } } if (pBindCur->dwPart & DBPART_LENGTH) { if (bReading) { if (!(pBindCur->dwPart & DBPART_VALUE)) cbDst = cbCol; // We didn't have the data convert to correct this *((DBLENGTH*)((BYTE*)(pDstData) + pBindCur->obLength)) = (dbStat == DBSTATUS_S_ISNULL) ? 0 : cbDst; } else *((DBLENGTH*)((BYTE*)(pSrcData) + pBindCur->obLength)) = cbDst; } if (pBindCur->dwPart & DBPART_STATUS) { if (bReading) *((DBSTATUS*)((BYTE*)(pDstData) + pBindCur->obStatus)) = dbStat; else *((DBSTATUS*)((BYTE*)(pSrcData) + pBindCur->obStatus)) = dbStat; } if (FAILED(hr)) { if (!bReading) { __if_exists(T::Fire_OnFieldChange) { if (/* pRow->m_status != DBPENDINGSTATUS_NEW && */ pRow->m_status != (DBPENDINGSTATUS_NEW | DBPENDINGSTATUS_UNCHANGED)) { pT->Fire_OnFieldChange(pT, hNotifyRow, pBinding->cBindings, rgColumns.GetData(), DBREASON_COLUMN_SET, DBEVENTPHASE_FAILEDTODO, TRUE); } } } bFailed = true; } else { bSucceeded = true; } } // Return error codes to the consumer if (bFailed) { __if_exists(T::Fire_OnFieldChange) { if( !bReading ) {// SendColumnSetFailureNotification( pT, hNotifyRow, pBinding, rgColumns ); SendRowsFirstChangeFailureNotification( pT, pRow, &hNotifyRow, bDeferred ); } } return (bSucceeded != false) ? DB_S_ERRORSOCCURRED : DB_E_ERRORSOCCURRED; } else { if (!bReading) { __if_exists(T::Fire_OnFieldChange) { if (/* pRow->m_status != DBPENDINGSTATUS_NEW && */ pRow->m_status != (DBPENDINGSTATUS_NEW | DBPENDINGSTATUS_UNCHANGED)) { pT->Fire_OnFieldChange(pT, hNotifyRow, pBinding->cBindings, rgColumns.GetData(), DBREASON_COLUMN_SET, DBEVENTPHASE_DIDEVENT, TRUE); } } } return hr; }}// IFRowsetImpltemplate <class T, class RowsetInterface, class RowClass = CSimpleRow, class MapClass = CAtlMap < RowClass::KeyType, RowClass* > >class ATL_NO_VTABLE IFRowsetImpl : public RowsetInterface{public: typedef RowClass _HRowClass; IFRowsetImpl() { m_iRowset = 0; m_bCanScrollBack = false; m_bCanFetchBack = false; m_bRemoveDeleted = true; m_bIRowsetUpdate = false; m_bReset = true; m_bExternalFetch = false; } ~IFRowsetImpl() { //for (int i = 0; i < m_rgRowHandles.GetCount(); i++) // delete (m_rgRowHandles.GetValueAt(i)); POSITION pos = m_rgRowHandles.GetStartPosition(); while( pos != NULL ) { MapClass::CPair *pPair = m_rgRowHandles.GetNext(pos); ATLASSERT( pPair != NULL ); delete pPair->m_value; } } HRESULT RefRows(DBCOUNTITEM cRows, const HROW rghRows[], DBREFCOUNT rgRefCounts[], DBROWSTATUS rgRowStatus[], BOOL bAdd) { ATLTRACE(atlTraceDBProvider, 2, _T("IFRowsetImpl::AddRefRows\n")); if (cRows == 0) return S_OK; if (rghRows == NULL) return E_INVALIDARG; T::ObjectLock cab((T*)this); BOOL bSuccess1 = FALSE; BOOL bFailed1 = FALSE; DBROWSTATUS rs; DWORD dwRef; __if_exists(T::Fire_OnRowChange) { // Maintain an array of handles w/ zero ref counts for notification CAtlArray<HROW> arrZeroHandles; } for (ULONG iRow = 0; iRow < cRows; iRow++) { HROW hRowCur = rghRows[iRow]; RowClass* pRow; bool bFound = m_rgRowHandles.Lookup((RowClass::KeyType)hRowCur, pRow); if (!bFound || pRow == NULL) { ATLTRACE(atlTraceDBProvider, 0, _T("Could not find HANDLE %x in list\n")); rs = DBROWSTATUS_E_INVALID; dwRef = 0; bFailed1 = TRUE; } else { if (pRow->m_status != DBPENDINGSTATUS_UNCHANGED && pRow->m_status != DBPENDINGSTATUS_INVALIDROW && pRow->m_dwRef == 0 && !bAdd) { if (rgRefCounts) rgRefCounts[iRow] = 0; if (rgRowStatus != NULL) rgRowStatus[iRow] = DBROWSTATUS_E_INVALID; bFailed1 = TRUE; continue; } // Check if we're in immediate or deferred mode CComVariant varDeferred; bool bDeferred; T* pT = (T*)this; HRESULT hr = pT->GetPropValue(&DBPROPSET_ROWSET, DBPROP_IRowsetUpdate, &varDeferred); (FAILED(hr) || varDeferred.boolVal == ATL_VARIANT_FALSE) ? bDeferred = false : bDeferred = true; if (!bDeferred && bAdd && pRow->m_status == DBPENDINGSTATUS_DELETED) { bFailed1 = TRUE; if (rgRowStatus != NULL) rgRowStatus[iRow] = DBROWSTATUS_E_DELETED; continue; } if (bAdd) dwRef = pRow->AddRefRow(); else { dwRef = pRow->ReleaseRow(); if ((pRow->m_status != DBPENDINGSTATUS_UNCHANGED && pRow->m_status != 0 && pRow->m_status != DBPENDINGSTATUS_INVALIDROW) && bDeferred) { if (rgRefCounts) rgRefCounts[iRow] = dwRef; if (rgRowStatus != NULL) rgRowStatus[iRow] = DBROWSTATUS_S_PENDINGCHANGES; bSuccess1 = TRUE; continue; } if (dwRef == 0) { __if_exists(T::Fire_OnRowsetChange) { _ATLTRY { arrZeroHandles.Add(hRowCur); } _ATLCATCH( e ) { _ATLDELETEEXCEPTION( e ); return E_FAIL; } } // Now determine if the DBPROP_REMOVEDELETED property // is ATL_VARIANT_FALSE. If so, then do NOT remove the // row. hr = pT->GetPropValue(&DBPROPSET_ROWSET, DBPROP_REMOVEDELETED, &varDeferred); if (FAILED(hr) || varDeferred.boolVal != ATL_VARIANT_FALSE) { delete pRow; m_rgRowHandles.RemoveKey((RowClass::KeyType)hRowCur); } } } bSuccess1 = TRUE; rs = DBROWSTATUS_S_OK; } if (rgRefCounts) rgRefCounts[iRow] = dwRef; if (rgRowStatus != NULL) rgRowStatus[iRow] = rs; } __if_exists(T::Fire_OnRowsetChange) { if (!bAdd && arrZeroHandles.GetCount() > 0) { T* pT = (T*)this; pT->Fire_OnRowChange(pT, (ULONG_PTR)arrZeroHandles.GetCount(), arrZeroHandles.GetData(), DBREASON_ROW_RELEASE, DBEVENTPHASE_DIDEVENT, FALSE); } } if (!bSuccess1 && !bFailed1) { ATLTRACE(atlTraceDBProvider, 0, _T("IFRowsetImpl::RefRows Unexpected state\n")); return E_FAIL;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -