Поделиться через


IKnowledgeSyncProvider::GetChangeBatch

Возвращает пакет изменений, содержащий метаданные элементов, которые отсутствовали в указанном наборе знаний от поставщика назначения.

HRESULT GetChangeBatch(
  DWORD dwBatchSize,
  ISyncKnowledge * pSyncKnowledge,
  ISyncChangeBatch ** ppSyncChangeBatch,
  IUnknown ** ppUnkDataRetriever);

Параметры

  • dwBatchSize
    [in] Запрошенное число изменений, которые должны быть включены в пакет изменений.
  • pSyncKnowledge
    [in] Набор знаний от поставщика назначения. Прежде чем набор знаний можно будет использовать для перечисления изменений, необходимо выполнить сопоставление набора знаний путем вызова метода ISyncKnowledge::MapRemoteToLocal в отношении набора знаний источника.
  • ppSyncChangeBatch
    [out] Возвращает пакет изменений, содержащий метаданные элемента для элементов, не включенных в состав pSyncKnowledge.
  • ppUnkDataRetriever
    [out] Возвращает объект, который может использоваться для получения информации об изменениях. Это может быть объект ISynchronousDataRetriever или другой объект, зависящий от поставщика.

Возвращаемое значение

  • S_OK

  • Коды ошибок, определяемые поставщиком

Замечания

Учтите, что dwBatchSize является лишь запрошенным количеством. Может быть возвращен больший или меньший пакет.

Примечания по реализации

Если после этого пакета больше нет изменений для отправки, то для возвращенного пакета изменений необходимо вызвать метод ISyncChangeBatchBase::SetLastBatch. В противном случае Sync Framework снова вызовет метод GetChangeBatch, чтобы получить следующий пакет изменений.

Пример

В приведенных ниже примерах показана реализация метода GetChangeBatch. В первом примере показано, как возвратить пакет изменений из объекта пользовательского хранилища метаданных и интерфейс получения данных из объекта пользовательского хранилища элементов. Во втором примере реализован метод m_pMetadataMgr->GetChangeBatch, вызываемый в первом примере. Этот метод перечисляет все элементы в хранилище метаданных и добавляет в возвращаемый пакет изменений элемент, если он не содержится в наборе знаний назначения.

STDMETHODIMP CXMLProvider::GetChangeBatch(
    DWORD dwBatchSize,
    ISyncKnowledge * pSyncKnowledge,
    ISyncChangeBatch ** ppSyncChangeBatch,
    IUnknown ** ppUnkDataRetriever)
{
    HRESULT hr = E_UNEXPECTED;

    if (NULL == pSyncKnowledge || NULL == ppSyncChangeBatch || NULL == ppUnkDataRetriever)
    {
        hr = E_POINTER;
    }
    else
    {
        _ASSERT(NULL != m_pMetadataMgr);
        hr = m_pMetadataMgr->GetChangeBatch(dwBatchSize, pSyncKnowledge, ppSyncChangeBatch);
        if (SUCCEEDED(hr))
        {
            hr = m_pItemStore->QueryInterface(IID_IUnknown, (void**)ppUnkDataRetriever);
        }
    }

    return hr;
}
STDMETHODIMP CMetadataMgr::GetChangeBatch(
    DWORD dwBatchSize,
    ISyncKnowledge *pSyncKnowledge,
    ISyncChangeBatch ** ppSyncChangeBatch)
{
    HRESULT hr = E_UNEXPECTED;

    ISyncChangeBatch* pChangeBatch = NULL;
    ISyncKnowledge* pMappedDestKnowledge = NULL;
    ISyncKnowledge* pSourceKnowledge = NULL;

    if (NULL == pSyncKnowledge || NULL == ppSyncChangeBatch)
    {
        hr = E_POINTER;
    }
    else
    {
        // Get our (source) knowledge object, map the remote (destination) knowledge for local use, 
        // and get our replica ID.
        GUID guidReplicaID;
        hr = GetKnowledge(&pSourceKnowledge);
        if (SUCCEEDED(hr))
        {
            hr = pSourceKnowledge->MapRemoteToLocal(pSyncKnowledge, &pMappedDestKnowledge);
            if (SUCCEEDED(hr))
            {
                ULONG cbID = sizeof(guidReplicaID);
                hr = GetReplicaId((BYTE*)&guidReplicaID, &cbID);
            }
        }

        if (SUCCEEDED(hr))
        {
            // Create a new change batch object.  We'll fill this object with changes to send.
            IProviderSyncServices* pProvSvc = NULL;
            // This helper function creates and initializes the IProviderSyncServices interface.
            hr = GetProviderSyncServices(&c_idParams, &pProvSvc);
            if (SUCCEEDED(hr))
            {
                hr = pProvSvc->CreateChangeBatch(pSyncKnowledge, NULL, &pChangeBatch);            

                pProvSvc->Release();
                pProvSvc = NULL;
            }
        }

        // Enumerate the items in our store and add new changes to the change batch.
        if (SUCCEEDED(hr))
        {
            // Begin an unordered group in our change batch. All change items will be added to this group.
            hr = pChangeBatch->BeginUnorderedGroup();
            if (SUCCEEDED(hr))
            {
                ULONG cFetched = 1;
                IItemMetadata* pItemMeta = NULL;
                SYNC_GID gidItem;
                ULONG cbgid = sizeof(gidItem);
                SYNC_VERSION verCur;
                SYNC_VERSION verCreate;
                hr = Reset();
                while (S_OK == hr)
                {
                    hr = Next(1, &pItemMeta, &cFetched);
                    if (S_OK == hr)
                    {
                        hr = pItemMeta->GetGlobalId((BYTE*)&gidItem, &cbgid);
                        if (SUCCEEDED(hr))
                        {
                            hr = pItemMeta->GetChangeVersion(&verCur);
                            if (SUCCEEDED(hr))
                            {
                                // Find out whether the destination already knows about this change.
                                hr = pMappedDestKnowledge->ContainsChange((BYTE*)&guidReplicaID,
                                    (BYTE*)&gidItem, &verCur);
                                if (S_FALSE == hr)
                                {
                                    // S_FALSE means the destination does not know about the 
                                    // change, so add it to the change batch.
                                    DWORD dwFlags = 0;
                                    BOOL fTomb = 0;
                                    hr = pItemMeta->GetIsDeleted(&fTomb);
                                    if (fTomb)
                                    {
                                        dwFlags = SYNC_CHANGE_FLAG_DELETED;                            
                                    }

                                    hr = pItemMeta->GetCreationVersion(&verCreate);
                                    if (SUCCEEDED(hr))
                                    {
                                        hr = pChangeBatch->AddItemMetadataToGroup((BYTE*)&guidReplicaID, 
                                            (BYTE*)&gidItem, &verCur, &verCreate, dwFlags, 0, NULL);
                                    }
                                }
                            }
                        }

                        pItemMeta->Release();
                    }
                }
            }

            if (SUCCEEDED(hr))
            {
                // We always send the entire set of changes, so every batch is the last batch. 
                // If this flag is not set Sync Framework will call GetChangeBatch again.
                hr = pChangeBatch->SetLastBatch();
            }

            if (SUCCEEDED(hr))
            {
                // Close the change batch group that contains our changes.
                hr = pChangeBatch->EndUnorderedGroup(pSourceKnowledge, TRUE);
            }
        }

        if (NULL != pChangeBatch)
        {
            if (SUCCEEDED(hr))
            {
                // Return the change batch we've constructed.  This will be sent to the 
                // destination provider.
                *ppSyncChangeBatch = pChangeBatch;
            }
            else
            {
                pChangeBatch->Release();            
            }
        }

        if (NULL != pMappedDestKnowledge)
        {
            pMappedDestKnowledge->Release();
        }
        if (NULL != pSourceKnowledge)
        {
            pSourceKnowledge->Release();
        }
    }

    return hr;
}

См. также

Справочник

Интерфейс IKnowledgeSyncProvider