Getting Started Storing Metadata
The metadata storage service helps store synchronization metadata for a provider that represents a replica that cannot otherwise store metadata. The metadata storage service uses a lightweight database that has a small memory and disk footprint, can be redistributed together with the provider, and is reliable.
The metadata storage service API clearly separates the metadata store from the interfaces and methods that are used to access the metadata store so that alternative stores can be implemented and used with minimal change to the provider.
The metadata storage service interfaces are single threaded. Calls can be made on any thread. However, a multithreaded application must provide appropriate thread synchronization when it is using these interfaces.
Creating the Metadata Store
The metadata storage service provides an implementation of the API that uses a lightweight database to store the metadata in a file.
Managed code A metadata store is represented by a SqlMetadataStore object. This object extends the MetadataStore abstract class. In addition to providing the base class methods for handling replica metadata and transactions, SqlMetadataStore provides methods for creating or opening the metadata store itself. To create a new store, call CreateStore. To open an existing store, call OpenStore.
Unmanaged code A metadata store is represented by an ISqlSyncMetadataStore interface object. This object extends the ISyncMetadataStore interface. In addition to providing the base interface methods for handling replica metadata and transactions, ISqlSyncMetadataStore provides methods for creating or opening the metadata store itself. To create an ISqlSyncMetadataStore object, pass CLSID_SyncMetadataStore and IID_ISqlSyncMetadataStore to CoCreateInstance. To create a new store, call ISqlSyncMetadataStore::CreateStore. To open an existing store, call ISqlSyncMetadataStore::OpenStore.
The metadata file is not secured against unauthorized access. To protect the metadata file, the folder that contains it must be properly secured, such as by using a Discretionary Access Control List (DACL). When the metadata file is stored in a remote location, the communication channel between the metadata storage service and the remote folder must be appropriately secured. To allow the user to delete the metadata file, the provider that creates the metadata file should put it somewhere the user can access. The provider that creates the metadata file must delete the metadata file when the provider is uninstalled.
When Sync Framework opens the metadata file by a remote mechanism, such as a UNC path, the metadata file cannot be simultaneously accessed by any other application on any computer, including an application on the machine where the metadata file is stored.
Replica metadata must be initialized before it can be used. Replica metadata can be initialized only one time for each metadata store. If custom fields or indexes are required, they must be defined when the replica metadata is initialized.
Managed code Initialize replica metadata by calling InitializeReplicaMetadata(SyncIdFormatGroup, SyncId, IEnumerableFieldSchema, IEnumerableIndexSchema).
Unmanaged code Initialize replica metadata by calling ISyncMetadataStore::InitializeReplicaMetadata.
To access replica metadata in an existing store, a replica metadata object must be obtained. A different replica metadata object exists for each replica ID. However, be aware that the metadata storage service protects against concurrent updates to the metadata store by allowing for only one replica metadata object to exist at a time for each replica ID. If an instance of the replica metadata object already exists, for a specified replica ID, in the process that is trying to open it, a reference to the existing object will be returned. If an instance of the replica metadata object already exists, for a specified replica ID, in a different process than the one that is trying to open it, the attempt will fail.
Managed code Get a replica metadata object by calling GetReplicaMetadata(SyncIdFormatGroup, SyncId).
Unmanaged code Get a replica metadata object by calling ISyncMetadataStore::GetReplicaMetadata.
The replica metadata object provides methods for accessing the metadata for a replica and for the items that are contained in the replica. For more information, see Accessing Replica Metadata.
Custom Item Fields
A set of custom fields can be defined for item metadata. Each field consists of a unique string name and a value. These fields can be used to store any additional metadata about an item that is not otherwise supported by the default set of item metadata. The fields can be accessed through various methods on ItemMetadata (for managed code) or IItemMetadata (for unmanaged code). These fields and their format, including size and data type, are defined when the replica metadata is initialized.
Managed code Specify custom fields by passing a FieldSchema object to InitializeReplicaMetadata(SyncIdFormatGroup, SyncId, IEnumerableFieldSchema, IEnumerableIndexSchema).
A set of index schemas can be defined so that sets of custom fields can be used as indexes to efficiently find items in the metadata store. An index schema can be defined as unique to ensure that the index defines a single item. Each field that is contained in an index schema must also exist in the custom field schema that is defined for the replica.
Managed code Specify index schemas by passing an IndexSchema object to InitializeReplicaMetadata(SyncIdFormatGroup, SyncId, IEnumerableFieldSchema, IEnumerableIndexSchema).
Transactions exist either implicitly or explicitly. Implicit transactions are supported only for reading data from the metadata store. An attempt to write to the metadata store without first starting an explicit transaction will throw ExplicitTransactionRequiredException (for managed code) or return SYNC_E_METADATA_ACTIVE_TRANSACTION_REQUIRED (for unmanaged code).
To set metadata by using managed code
Start an explicit transaction by calling BeginTransaction. Commit changes that were made during the transaction by calling CommitTransaction. Discard changes that were made during the transaction by calling RollbackTransaction.
To set metadata by using unmanaged code
Start an explicit transaction by calling ISyncMetadataStore::BeginTransaction. Commit changes that were made during the transaction by calling ISyncMetadataStore::CommitTransaction. Discard changes that were made during the transaction by calling ISyncMetadataStore::RollbackTransaction.
This transaction service applies only to the metadata that is stored in the metadata store. Any item data that is saved to the item store on the replica is not included in this transaction.