IKnowledgeSyncProvider::GetChangeBatch
Obtient un lot de modifications qui contient les métadonnées des éléments qui ne sont pas contenus dans la connaissance spécifiée du fournisseur de destination.
Syntaxe
HRESULT GetChangeBatch(
DWORD dwBatchSize,
ISyncKnowledge * pSyncKnowledge,
ISyncChangeBatch ** ppSyncChangeBatch,
IUnknown ** ppUnkDataRetriever);
Paramètres
dwBatchSize
[in] Nombre demandé de modifications à inclure dans le lot de modifications.pSyncKnowledge
[in] Connaissance du fournisseur de destination. Cette connaissance doit être mappée en appelant la méthode ISyncKnowledge::MapRemoteToLocal sur la connaissance source avant toute utilisation pour l'énumération des modifications.ppSyncChangeBatch
[out] Retourne un lot de modifications qui contient les métadonnées d'élément pour les éléments qui ne sont pas contenus dans pSyncKnowledge.ppUnkDataRetriever
[out] Retourne un objet qui peut être utilisé pour récupérer des données de modification. Il peut s'agir d'un objet ISynchronousDataRetriever ou d'un objet spécifique au fournisseur.
Valeur de retour
S_OK
Codes d'erreur déterminés par le fournisseur
Notes
Gardez à l'esprit que dwBatchSize est uniquement un nombre demandé. Un lot plus petit ou plus grand peut être retourné.
Remarques à l'attention des implémenteurs
S'il n'y a plus de modifications à envoyer après ce lot, vous devez appeler ISyncChangeBatchBase::SetLastBatch sur le lot de modifications retourné. Sinon, Sync Framework appelle encore la méthode GetChangeBatch pour récupérer un autre lot de modifications.
Exemple
Les exemples suivants sont une implémentation de GetChangeBatch. Le premier exemple montre comment obtenir un lot de modifications d'un objet de la banque de métadonnées personnalisée et une interface d'extracteur de données d'un objet du magasin d'éléments personnalisé. Le second exemple implémente la méthode m_pMetadataMgr->GetChangeBatch qui est appelée dans le premier exemple. Cette méthode énumère tous les éléments dans la banque de métadonnées et ajoute un élément au lot de modifications retourné si l'élément n'est pas contenu dans la connaissance de destination.
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;
}