locked
Wanting to see change versions of files associated with FileProvider 2.1 RRS feed

  • Question

  • I've got a sync provider I've written that syncs between a sync framework file provider and my own azure provider.  I'm getting unexpected results in syncing and I'd like to figure out why.  I can iterate through my own metadata on the azure side to see what the changeversion is from my metadata, but can't figure out how to iterate through the metadata of the file provider.  That is, say I have 4 files associated with the file provider.  I want to be able to generate a simple list that shows me the: FileName,FileSize,CreateDate,LastUpdatedate,ChangeVersion.

    Any suggestions?


    Peter Kellner http://peterkellner.net Microsoft MVP • ASPInsider
    Thursday, April 28, 2011 9:51 PM

Answers

  • Hi,

    Your code has a few issues.

    1. Instead of define a new SyncIdFormatGroup, you should use the public property FileSyncProvider.IdFormats.

    2. The ReplicaId in Metadatastore file "filesync.metadata" is in native format, you passed in a Guid value is managed format. You need to convert the format. For example, native replica id [4fd75571cd67f641b4b49e9dd41785ea] is showed as "7155d74f-67cd-41f6-b4b4-9e9dd41785ea" in managed code.

    3. Instead of using SqlMetadataStore.GetReplicaMetadata(...), you can use GetSingleReplicaMetadata() instead as long as you only store one replica in the metadata file.

    After working around these issues, you can call ReplicaMetadata.GetAllItems to check their creation and update version with their globalIds.

    Thanks,
    Dong

     


    This posting is provided AS IS with no warranties, and confers no rights.
    Monday, May 2, 2011 10:48 PM
  • Dong,

    I think our replies crossed somehow, are you using an offline reader?  Anyhow, I did find the GetSingleReplicaMetadata() you suggest in my follow on post from 40 minutes ago. that means (I believe) that the SyncIdFormtGroup does not matter anymore.  Also, I'm passing the Guid for replicaID in the constructor of the file provider so that should not be a problem. 

    My current problem is that when I try to get the filenameuri and timestamp values out of the metadata, I keep getting errors saying those are not valid columns.  Please review my question below and suggest a solution.

    -Peter


    Peter Kellner http://peterkellner.net Microsoft MVP • ASPInsider
    Monday, May 2, 2011 11:16 PM
  • I finally decided to go into a file hex editor to look at the metadata so I could guess some column names.  That lead me to several column names which I'm hoping is good enough. I never did figure out how to read the filehash column, but I did get the dates and filenames I really need.

    I did a blog post about this if anyone wants to know more details.

    http://connectionroad.com/synchronization-technology/246/how-to-get-metadata-from-the-microsoft-sync-framework-file-provider/

     


    Peter Kellner http://peterkellner.net Microsoft MVP • ASPInsider
    Tuesday, May 3, 2011 1:51 AM

All replies

  • Hi,

    The FileSyncProvider metadata file is a SyncFx Metadata store. You may consider reading it with SyncFx matadata store service APIs: http://msdn.microsoft.com/en-us/library/microsoft.synchronization.metadatastorage(v=SQL.110).aspx.

    Thanks,
    Dong


    This posting is provided AS IS with no warranties, and confers no rights.
    Friday, April 29, 2011 12:21 AM
  • Dong,

    I"ve spend several hours going through the metadata api and I can't figure out how to find the metadata associated with a default fileprovider.  I've tried code like what is below, but that does not work. Pease try and be more specific with your answer in addition to sending me to a generic documentation link.

                  var fileProviderReplicadGuid = new Guid("5b75fc0a-4652-467a-bc49-52269bd2f112");
    
                  fileSyncProvider = new FileSyncProvider(localPath) { PreviewMode = previewMode };
    
                  fileSyncProvider = new FileSyncProvider(fileProviderReplicadGuid, localPath) { PreviewMode = previewMode };
    
                  string fileNameMetaData = Path.Combine(fileSyncProvider.MetadataDirectoryPath,
                                      fileSyncProvider.MetadataFileName);
    
                  var syncIdFormatGroup = new SyncIdFormatGroup();
                  syncIdFormatGroup.ChangeUnitIdFormat.IsVariableLength = false;
                  syncIdFormatGroup.ChangeUnitIdFormat.Length = 4; // not used but defined
                  syncIdFormatGroup.ItemIdFormat.IsVariableLength = false;
                  syncIdFormatGroup.ItemIdFormat.Length = 24;
                  // sizeof(SYNCGID) == sizeof(ulong)(8)+sizeof(GUID)(16)  
                  syncIdFormatGroup.ReplicaIdFormat.IsVariableLength = false;
                  syncIdFormatGroup.ReplicaIdFormat.Length = 16; // sizeof (GUID)
    
                  var metadataStore = SqlMetadataStore.OpenStore(fileNameMetaData);
    
                  var replicaId = new SyncId(fileSyncProvider.ReplicaId);
                  var replicaMetaData = metadataStore.GetReplicaMetadata(syncIdFormatGroup, replicaId);
                  DisplayMetaDataForDebug(replicaMetaData);
    


    Peter Kellner http://peterkellner.net Microsoft MVP • ASPInsider
    Monday, May 2, 2011 8:00 PM
  • I'm continuing down the path and have figured out how to open the metadata but I don't know what the name of the metadata fields are and I don't see a call to enumerate them.  Here is what I have.  All three test names return:

    "The metadata store method requires a valid field name."

     

                  var fileProviderReplicadGuid = new Guid("5b75fc0a-4652-467a-bc49-52269bd2f112");
                  fileSyncProvider = new FileSyncProvider(fileProviderReplicadGuid,
                                      localPath, null, FileSyncOptions.None,
                                      @"c:\tmp\metadata\", "metafilehere.dat", "c:\\temp",
                                      "") {PreviewMode = previewMode};
    
                  string fileNameMetaData = Path.Combine(fileSyncProvider.MetadataDirectoryPath,
                                      fileSyncProvider.MetadataFileName);
    
                  var syncIdFormatGroup = new SyncIdFormatGroup();
                  syncIdFormatGroup.ChangeUnitIdFormat.IsVariableLength = false;
                  syncIdFormatGroup.ChangeUnitIdFormat.Length = 4; // not used but defined
                  syncIdFormatGroup.ItemIdFormat.IsVariableLength = false;
                  syncIdFormatGroup.ItemIdFormat.Length = 24;
                  // sizeof(SYNCGID) == sizeof(ulong)(8)+sizeof(GUID)(16)  
                  syncIdFormatGroup.ReplicaIdFormat.IsVariableLength = false;
                  syncIdFormatGroup.ReplicaIdFormat.Length = 16; // sizeof (GUID)
    
                  using (var metadataStore = SqlMetadataStore.OpenStore(fileNameMetaData))
                  {
                    var singleReplicaMetadata = metadataStore.GetSingleReplicaMetadata();
                    uint totalItemCount;
                    uint deletedItemCount;
                    singleReplicaMetadata.GetItemCount(out totalItemCount, out deletedItemCount);
                    var allItems = singleReplicaMetadata.GetAllItems(true);
                    foreach (var rec in allItems)
                    {
                      // these next 4 seem to work correctly
                      var changeVersion = rec.ChangeVersion;
                      var createVersion = rec.CreationVersion;
                      var globalId = rec.GlobalId;
                      var isDeleted = rec.IsDeleted;
    
                      // these two fields return com errors saying field not found.
                      // what are the names?
                      List<string> trialFieldNames = new List<string>()
                                        {
                                          "filenameuri",
                                          "filename",
                                          "timestamp"
                                        };
                      foreach (var trialName in trialFieldNames)
                      {
                        try
                        {
                          var fileName = rec.GetStringField(trialName);
                          Console.WriteLine("filename worked: " + fileName);
                        }
                        catch (Exception e)
                        {
                          Console.WriteLine(e);
                        }
    
                      }
                    }
                    metadataStore.Dispose();
                  }
                }
    

     


    Peter Kellner http://peterkellner.net Microsoft MVP • ASPInsider
    Monday, May 2, 2011 9:49 PM
  • Hi,

    Your code has a few issues.

    1. Instead of define a new SyncIdFormatGroup, you should use the public property FileSyncProvider.IdFormats.

    2. The ReplicaId in Metadatastore file "filesync.metadata" is in native format, you passed in a Guid value is managed format. You need to convert the format. For example, native replica id [4fd75571cd67f641b4b49e9dd41785ea] is showed as "7155d74f-67cd-41f6-b4b4-9e9dd41785ea" in managed code.

    3. Instead of using SqlMetadataStore.GetReplicaMetadata(...), you can use GetSingleReplicaMetadata() instead as long as you only store one replica in the metadata file.

    After working around these issues, you can call ReplicaMetadata.GetAllItems to check their creation and update version with their globalIds.

    Thanks,
    Dong

     


    This posting is provided AS IS with no warranties, and confers no rights.
    Monday, May 2, 2011 10:48 PM
  • Dong,

    I think our replies crossed somehow, are you using an offline reader?  Anyhow, I did find the GetSingleReplicaMetadata() you suggest in my follow on post from 40 minutes ago. that means (I believe) that the SyncIdFormtGroup does not matter anymore.  Also, I'm passing the Guid for replicaID in the constructor of the file provider so that should not be a problem. 

    My current problem is that when I try to get the filenameuri and timestamp values out of the metadata, I keep getting errors saying those are not valid columns.  Please review my question below and suggest a solution.

    -Peter


    Peter Kellner http://peterkellner.net Microsoft MVP • ASPInsider
    Monday, May 2, 2011 11:16 PM
  • I finally decided to go into a file hex editor to look at the metadata so I could guess some column names.  That lead me to several column names which I'm hoping is good enough. I never did figure out how to read the filehash column, but I did get the dates and filenames I really need.

    I did a blog post about this if anyone wants to know more details.

    http://connectionroad.com/synchronization-technology/246/how-to-get-metadata-from-the-microsoft-sync-framework-file-provider/

     


    Peter Kellner http://peterkellner.net Microsoft MVP • ASPInsider
    Tuesday, May 3, 2011 1:51 AM