다음을 통해 공유


IKnowledgeSyncProvider::ProcessChangeBatch

충돌을 검색하고 항목 저장소에 변경 내용을 적용하여 변경 내용 집합을 처리합니다.

HRESULT ProcessChangeBatch(
  CONFLICT_RESOLUTION_POLICY resolutionPolicy,
  ISyncChangeBatch * pSourceChangeBatch,
  IUnknown * pUnkDataRetriever,
  ISyncCallback * pCallback,
  SYNC_SESSION_STATISTICS * pSyncSessionStatistics);

매개 변수

  • resolutionPolicy
    [in] 이 메서드가 변경 내용을 적용할 때 사용할 충돌 해결 정책입니다.
  • pSourceChangeBatch
    [in] 로컬로 적용할 원본 공급자의 일괄 변경 내용입니다.
  • pUnkDataRetriever
    [in] 변경 내용 데이터를 검색하는 데 사용할 수 있는 개체로서 ISynchronousDataRetriever 개체이거나 공급자 관련 개체일 수 있습니다.
  • pCallback
    [in] 변경 내용 적용 중에 이벤트 알림을 받는 개체입니다.
  • pSyncSessionStatistics
    [in, out] 변경 내용 통계를 추적합니다. 사용자 지정 변경 내용 적용을 사용하는 공급자의 경우 이 개체는 변경 내용 적용 결과로 업데이트되어야 합니다.

반환 값

  • S_OK

  • 공급자 고유의 오류 코드입니다.

주의

원본 변경 내용에 변경 단위의 변경 내용이 포함된 경우 대상 공급자는 변경 적용자에게 보낸 대상 버전의 일괄 처리에 포함할 변경 단위 버전을 결정해야 합니다(변경 단위 버전이 있는 경우). 포함할 변경 단위 버전은 원본 공급자의 변경 내용 유형 및 해당 항목이 대상 복제본에서 삭제된 것으로 표시되는지 여부에 따라 결정됩니다. 자세한 내용은 변경 단위 동기화를 참조하십시오.

예제

다음 예제에서는 ProcessChangeBatch를 구현하는 방법을 보여 줍니다. 첫 번째 예제에서는 ISynchronousNotifyingChangeApplier 개체를 만들고 ISynchronousNotifyingChangeApplier::ApplyChanges를 호출하여 대상 복제본에 변경 내용을 적용하는 방법을 보여 줍니다. 두 번째 예제에서는 첫 번째 예제에서 사용하는 m_pMetadataMgr->GetItemBatchVersions 메서드를 구현합니다. 이 메서드는 원본 일괄 변경 내용에 포함된 변경 내용을 열거하고 IDestinationChangeVersionsBuilder 개체를 사용하여 해당하는 대상 버전의 목록을 만듭니다.

STDMETHODIMP CXMLProvider::ProcessChangeBatch(
    CONFLICT_RESOLUTION_POLICY resolutionPolicy,
    ISyncChangeBatch * pSourceChangeBatch,
    IUnknown * pUnkDataRetriever,
    ISyncCallback * pCallback,
    SYNC_SESSION_STATISTICS * pSyncSessionStatistics)
{
    HRESULT hr = E_UNEXPECTED;

    if (NULL == pSourceChangeBatch || NULL == pUnkDataRetriever || NULL == pSyncSessionStatistics)
    {
        hr = E_POINTER;
    }
    else
    {
        IEnumSyncChanges* pDestinationChangeEnum = NULL;

        _ASSERT(NULL != m_pMetadataMgr);

        // Obtain the local (destination) versions for the items in the source change batch.
        hr = m_pMetadataMgr->GetItemBatchVersions(pSourceChangeBatch, &pDestinationChangeEnum);
        if (SUCCEEDED(hr))
        {
            IProviderSyncServices* pProviderSvc = NULL;
            hr = GetProviderSyncServices(&c_idParams, &pProviderSvc);
            if (SUCCEEDED(hr))
            {
                // Create a standard change applier from Sync Framework.
                ISynchronousNotifyingChangeApplier* pChangeApplier = NULL;
                hr = pProviderSvc->CreateChangeApplier(IID_ISynchronousNotifyingChangeApplier,
                    (void**)&pChangeApplier);
                if (SUCCEEDED(hr))
                {
                    ISyncKnowledge* pDestinationKnowledge = NULL;
                    hr = m_pMetadataMgr->GetKnowledge(&pDestinationKnowledge);
                    if (SUCCEEDED(hr))
                    {
                        // Have the change applier process the change batch and apply changes.
                        // This method will call the change applier target methods to save
                        // changes and conflicts.  It will also pass the data retriever
                        // interface to the change applier target so it can retrieve item data.
                        hr = pChangeApplier->ApplyChanges(resolutionPolicy, pSourceChangeBatch, 
                            pUnkDataRetriever, pDestinationChangeEnum, pDestinationKnowledge, 
                            NULL, this, m_pSessionState, pCallback);
                        
                        pDestinationKnowledge->Release();
                    }

                    pChangeApplier->Release();
                }

                pProviderSvc->Release();
            }

            pDestinationChangeEnum->Release();
        }
    }

    return hr;
}
STDMETHODIMP CMetadataMgr::GetItemBatchVersions(
    ISyncChangeBatch * pRemoteSyncChangeBatch,
    IEnumSyncChanges ** ppLocalVersionsEnum)
{
    HRESULT hr = E_UNEXPECTED;

    if (NULL == pRemoteSyncChangeBatch || NULL == ppLocalVersionsEnum)
    {
        hr = E_POINTER;
    }
    else
    {
        IProviderSyncServices* pProvSvc;
        hr = GetProviderSyncServices(&c_idParams, &pProvSvc);
        if (SUCCEEDED(hr))
        {
            IDestinationChangeVersionsBuilder* pDestChangeBuilder = NULL;
            hr = pProvSvc->CreateDestinationChangeVersionsBuilder(&pDestChangeBuilder);
            if (SUCCEEDED(hr))
            {
                IEnumSyncChanges* pRemoteEnum = NULL;
                hr = pRemoteSyncChangeBatch->GetChangeEnumerator(&pRemoteEnum);
                if (SUCCEEDED(hr))
                {
                    ULONG cFetched;

                    ISyncChange* pChange;
                    SYNC_GID gidItem;
                    DWORD cbID = sizeof(gidItem);
                    DWORD dwFlags;
                    SYNC_VERSION verCurrent;
                    SYNC_VERSION verCreation;
                    HRESULT hrEnum = S_OK;
                    while (S_OK == hrEnum && SUCCEEDED(hr))
                    {
                        pChange = NULL;
                        hrEnum = pRemoteEnum->Next(1, &pChange, &cFetched);
                        if (S_OK == hrEnum)
                        {
                            hr = pChange->GetRootItemId((BYTE*)&gidItem, &cbID);
                            if (SUCCEEDED(hr))
                            {
                                // Try to find the item in the local (destination) metadata.
                                IItemMetadata* pItem = NULL;
                                hr = FindItemMetadataByGlobalId((BYTE*)&gidItem, &pItem);
                                if (S_OK == hr)
                                {
                                    // S_OK means the item exists in our local store.
                                    // Extract its version and tombstone information.
                                    dwFlags = 0;

                                    BOOL fTombstone = FALSE;
                                    hr = pItem->GetIsDeleted(&fTombstone);
                                    if (SUCCEEDED(hr))
                                    {
                                        if (fTombstone)
                                        {
                                            dwFlags = SYNC_CHANGE_FLAG_DELETED;
                                        }
                                    }

                                    if (SUCCEEDED(hr))
                                    {
                                        hr = pItem->GetChangeVersion(&verCurrent);
                                        if (SUCCEEDED(hr))
                                        {
                                            hr = pItem->GetCreationVersion(&verCreation);                                            
                                        }
                                    }

                                    pItem->Release();
                                }
                                else if (S_FALSE == hr)
                                {
                                    // S_FALSE means this item does not exist in our local store.
                                    // Set versions to 0 and flag it as a new item.
                                    verCurrent.dwLastUpdatingReplicaKey = 0;
                                    verCurrent.ullTickCount = 0;
                                    verCreation.dwLastUpdatingReplicaKey = 0;
                                    verCreation.ullTickCount = 0;
                                    dwFlags = SYNC_CHANGE_FLAG_DOES_NOT_EXIST;
                                }

                                if (SUCCEEDED(hr))
                                {
                                    // Add the item to the batch of destination versions.
                                    GUID guidReplicaID = GUID_NULL;
                                    ULONG cbID = sizeof(guidReplicaID);
                                    hr = GetReplicaId((BYTE*)&guidReplicaID, &cbID);
                                    if (SUCCEEDED(hr))
                                    {
                                        hr = pDestChangeBuilder->AddItemMetadata((BYTE*)&guidReplicaID,
                                            (BYTE*)&gidItem, &verCurrent, &verCreation, dwFlags, NULL);
                                    }
                                }
                            }

                            pChange->Release();
                        }
                    }

                    if (FAILED(hrEnum))
                    {
                        hr = hrEnum;                    
                    }

                    pRemoteEnum->Release();                
                }

                if (SUCCEEDED(hr))
                {
                    hr = pDestChangeBuilder->GetChangeEnumerator(ppLocalVersionsEnum);               
                }

                pDestChangeBuilder->Release();
            }

            pProvSvc->Release();        
        }
    }

    return hr;
}

참고 항목

참조

IKnowledgeSyncProvider 인터페이스
CONFLICT_RESOLUTION_POLICY 열거형