Upgrading the Metadata Store Version
The metadata storage service stores replica and item metadata in a lightweight database. The metadata is stored in a specific table schema and binary format that might change as new versions of Sync Framework are released. Additionally, custom provider fields in the database could change as a developer releases new versions of a particular provider. Sync Framework provides support for upgrading the metadata store both because of Sync Framework version changes and because of provider version changes.
Sync Framework also provides support for accessing the metadata store from components with different versions without upgrading the metadata store itself. For more information, see Accessing Metadata from Components with Different Versions.
Upgrading Because the Sync Framework Version Has Changed
The metadata store schema and file format are different in Sync Framework 2.1 and 2.0 than in Sync Framework 1.0. The metadata store file can either be kept in the 1.0 format or, for greater efficiency, the file can be upgraded to the new format.
The metadata store file upgrade cannot be undone. A file in the new format cannot be downgraded back to the 1.0 format.
When a metadata store file in the 1.0 format is opened by Sync Framework 2.1 or 2.0, it is automatically upgraded to the new format, unless the provider registers to receive notification of the upgrade and indicates that the metadata storage service should not upgrade the file format. To control whether the upgrade occurs, take the following steps.
Before opening the metadata store file, register to receive the MetadataStoreUpgradeStart event (for managed code) or register an IMetadataStoreUpgradeCallback object (for unmanaged code). To register the IMetadataStoreUpgradeCallback, call ISyncMetadataStore2::SetMetadataStoreUpgradeNotificationCallback.
Sync Framework detects that an upgrade is needed, and calls the MetadataStoreUpgradeStart event handler (for managed code) or IMetadataStoreUpgradeCallback::OnMetadataStoreFileUpgradeStart method (for unmanaged code).
The provider indicates whether the metadata store file should be upgraded, by using the SkipUpgrade property of the UpgradeStartEventArgs object (for managed code) or the pfSkipUpgrade parameter of the IMetadataStoreUpgradeCallback::OnMetadataStoreFileUpgradeStart method (for unmanaged code).
Upgrading Because the Provider Version Has Changed
A provider sets the provider version that is compatible with metadata for a replica by using ProviderVersion (for managed code) or IReplicaMetadata2::SetProviderVersion (for unmanaged code). When a provider opens a metadata store, it can check the provider version that is associated with the metadata for a replica by using ProviderVersion (for managed code) or IReplicaMetadata2::GetProviderVersion (for unmanaged code). When the version of the provider that opens the metadata store is different than the provider version that is stored in the metadata, the provider can upgrade the metadata schema for the replica. To upgrade the metadata schema, take the following steps.
Serialize the metadata for the replica to the canonical format by using SyncMetadataStoreSerializer (for managed code) or ISyncMetadataStoreSerializer::SerializeReplicaMetadata (for unmanaged code).
Remove the metadata for the replica from the metadata store by using RemoveReplicaMetadata(SyncIdFormatGroup, SyncId) (for managed code) or ISyncMetadataStore2::RemoveReplicaMetadata (for unmanaged code).
Initialize new metadata for the replica in the metadata store by using InitializeReplicaMetadata(SyncIdFormatGroup, SyncId, IEnumerableFieldSchema, IEnumerableIndexSchema) (for managed code) or ISyncMetadataStore::InitializeReplicaMetadata (for unmanaged code). In this call, specify the custom columns and indexes from the upgraded metadata schema.
Import the metadata that was serialized in step 1 by using DeserializeReplicaMetadata(String, UInt32, IProviderUpgradeCallback) (for managed code) or ISyncMetadataStoreSerializer::DeserializeReplicaMetadata (for unmanaged code). Specify the upgraded provider version in this call, and provide an IProviderUpgradeCallback (for managed code) or IProviderMetadataUpgradeCallback (for unmanaged code) object that will receive notification of events that occur during the upgrade.
During the upgrade, OnCustomReplicaMetadataDeserialized(Byte) (for managed code) or IProviderMetadataUpgradeCallback::OnReplicaCustomFieldDeserialized (for unmanaged code) is called to allow the provider to make any changes to the custom metadata field of the replica.
During the upgrade, OnItemMetadataDeserialized(ItemMetadata, DictionaryString, SyncFieldValue) (for managed code) or IProviderMetadataUpgradeCallback::OnItemMetadataDeserialized (for unmanaged code) is called one time for each item that is deserialized, to allow the provider to make any changes to the metadata for an item.
Metadata Compatibility Considerations
When you release a new version of a provider, you should be aware of the following considerations that relate to metadata compatibility:
Formats for replica IDs, item IDs, and so on (which are specified in the SyncIdFormatGroup (for managed code) or ID_PARAMETERS Structure (for unmanaged code) must be the same across all instances and versions of a provider within a particular synchronization community. This is a general rule, but it is restated here for completeness.
A replica's custom field cannot change in an incompatible way. This field is a BLOB that is serialized and deserialized without intervention from Sync Framework. Do not change the structure of the field in a way that prevents an earlier provider version from reading or writing to the field.
A provider’s custom column and index schema can change between provider versions. These schemas are optionally specified in the InitializeReplicaMetadata(SyncIdFormatGroup, SyncId, IEnumerableFieldSchema, IEnumerableIndexSchema) method (for managed code) or ISyncMetadataStore::InitializeReplicaMetadata method (for unmanaged code). However, be aware of the following:
The provider cannot make incompatible changes to the metadata schema. For example, you cannot remove a custom field that a previous provider required to be updated for every item update.
A new version of a provider can add custom columns only if updating those columns is optional. The previous version of the provider will not be aware that these columns exist.
Custom column names and values are serialized, but data types for those columns, indexes, and other schema information are not. This means that custom columns and indexes must exist in the metadata store before importing metadata from a canonical file.
Column data types cannot be changed in a newer version of a provider. This could result in deserialization errors for previous versions of a provider.