IKnowledgeSyncProvider::GetChangeBatch
Ruft einen Änderungsbatch mit Elementmetadaten für Elemente ab, die nicht im angegebenen Wissen des Zielanbieters enthalten sind.
HRESULT GetChangeBatch(
DWORD dwBatchSize,
ISyncKnowledge * pSyncKnowledge,
ISyncChangeBatch ** ppSyncChangeBatch,
IUnknown ** ppUnkDataRetriever);
Parameter
- dwBatchSize
[in] Die angeforderte Anzahl von Änderungen, die der Änderungsbatch umfassen soll.
- pSyncKnowledge
[in] Das Wissen des Zielanbieters. Dieses Wissen muss durch einen Aufruf von ISyncKnowledge::MapRemoteToLocal dem Quellwissen zugeordnet werden, bevor es für die Änderungsenumeration verwendet werden kann.
- ppSyncChangeBatch
[out] Gibt einen Änderungsbatch zurück, der Elementmetadaten für Elemente enthält, die nicht in pSyncKnowledge enthalten sind.
- ppUnkDataRetriever
[out] Gibt ein Objekt zurück, mit dem Änderungsdaten abgerufen werden können. Hierbei kann es sich um ein ISynchronousDataRetriever-Objekt oder ein anbieterspezifisches Objekt handeln.
Rückgabewert
S_OK
Vom Anbieter bestimmte Fehlercodes.
Hinweise
Beachten Sie, dass dwBatchSize nur eine angeforderte Anzahl ist. Es kann ein kleinerer oder größerer Batch zurückgegeben werden.
Hinweise für Implementierer
Wenn nach diesem Batch keine zu sendenden Änderungen mehr vorliegen, muss ISyncChangeBatchBase::SetLastBatch für den zurückgegebenen Änderungsbatch aufgerufen werden. Andernfalls wird GetChangeBatch von Sync Framework erneut aufgerufen, um einen weiteren Batch von Änderungen abzurufen.
Beispiel
Bei den folgenden Beispielen handelt es sich um eine Implementierung von GetChangeBatch. Im ersten Beispiel wird veranschaulicht, wie ein benutzerdefiniertes Elementspeicherobjekt einen Batch von Änderungen von einem benutzerdefinierten Metadatenspeicherobjekt und eine Datenabruferschnittstelle von einem benutzerdefinierten Elementspeicherobjekt abruft. Im zweiten Beispiel wird die m_pMetadataMgr->GetChangeBatch
-Methode implementiert, die im ersten Beispiel aufgerufen wird. Diese Methode listet alle Elemente im Metadatenspeicher auf und fügt dem zurückgegebenen Änderungsbatch ein Element hinzu, wenn das Element nicht im Zielwissen enthalten ist.
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;
}