/// <summary> /// Generate the sync preview containing actions to be executed. /// The returned SyncPreviewResult can then be passed to Synchronize method /// as an argument for the actions to be executed. /// </summary> /// <exception cref="DirectoryNotFoundException"></exception> public SyncPreviewResult GenerateSyncPreview(StatusCallbackDelegate statusCallback) { OnStatusChanged(new SyncStatusChangedEventArgs(m_ResourceManager.GetString("lbl_peparingToSync"))); // Load actions to be executed. IList <SyncAction> actions = actProvider.Load(_job.SyncSource.ID, SourceOption.SOURCE_ID_NOT_EQUALS); // Generate current folder's metadata FileMetaData currentItems = MetaDataProvider.GenerateFileMetadata(_job.SyncSource.Path, _job.SyncSource.ID, false, statusCallback); // Load current folder metadata from database FileMetaData oldCurrentItems = mdProvider.LoadFileMetadata(_job.SyncSource.ID, SourceOption.SOURCE_ID_EQUALS); // Load the other folder metadata from database FileMetaData oldOtherItems = mdProvider.LoadFileMetadata(_job.SyncSource.ID, SourceOption.SOURCE_ID_NOT_EQUALS); return(new SyncPreviewResult(actions, currentItems, oldCurrentItems, oldOtherItems)); }
private void SaveActionsAndDirtyFiles(IList <SyncAction> actions) { FileMetaData fileMetaData = MetaDataProvider.GenerateFileMetadata(_job.IntermediaryStorage.DirtyFolderPath, "", false, true); int totalProgress = actions.Count; int currProgress = 0; foreach (SyncAction a in actions) { if (!Validator.SyncJobParamsValidated(_job.Name, _job.IntermediaryStorage.Path, _job.SyncSource.Path, null)) { return; } try { OnProgressChanged(new SyncProgressChangedEventArgs(++currProgress, totalProgress)); OnSyncFileChanged(new SyncFileChangedEventArgs(a.ChangeType, a.RelativeFilePath)); FileMetaDataItem item = new FileMetaDataItem("", a.RelativeFilePath, a.FileHash, DateTime.Now, 0, 0); if (a.ChangeType == ChangeType.NEWLY_CREATED && !fileMetaData.MetaDataItems.Contains(item, new FileMetaDataItemComparer())) { SyncExecutor.CopyToDirtyFolderAndUpdateActionTable(a, _job); } else { actProvider.Add(a); } log.Add(new LogActivity(a.RelativeFilePath, a.ChangeType.ToString(), "SUCCESS")); } catch (OutOfDiskSpaceException) { log.Add(new LogActivity(a.RelativeFilePath, a.ChangeType.ToString(), "FAIL")); throw; } catch (Exception) { log.Add(new LogActivity(a.RelativeFilePath, a.ChangeType.ToString(), "FAIL")); throw; } } }
public static FileMetaData GenerateFileMetadata(string fromPath, string id, bool excludeHidden, StatusCallbackDelegate statusCallback) { FileMetaData fileMetadata = new FileMetaData(id, fromPath); DirectoryInfo di = new DirectoryInfo(fromPath); AddDirectorySecurity(fromPath); FileInfo[] files = null; if (statusCallback != null) { statusCallback("Reading files from: " + fromPath); } files = di.GetFiles("*.*", SearchOption.AllDirectories); if (files == null) { return(new FileMetaData(id, fromPath)); } IEnumerable <FileInfo> noHiddenFiles = from file in files where excludeHidden ? !Files.FileUtils.IsFileHidden(file.FullName) : true select file; files = noHiddenFiles.ToArray <FileInfo>(); foreach (FileInfo f in files) { try { if (statusCallback != null) { statusCallback(string.Format("Processing file: {0}", f.FullName)); } fileMetadata.MetaDataItems.Add(new FileMetaDataItem(id, OneSync.Files.FileUtils.GetRelativePath(fromPath, f.FullName), Files.FileUtils.GetFileHash(f.FullName), f.LastWriteTime, (uint)0, (uint)0)); }catch (Exception) { } } return(fileMetadata); }
private void GeneratePreview(FileMetaData currentMetadata, FileMetaData oldCurrentMetadata) { //By comparing current metadata and the old metadata from previous sync of a sync folder //we could know the dirty items of the folder. var comparerCurrent = new FileMetaDataComparer(currentMetadata, oldCurrentMetadata); var dirtyItemsInCurrent = new List <FileMetaDataItem>(); dirtyItemsInCurrent.AddRange(comparerCurrent.LeftOnly); dirtyItemsInCurrent.AddRange(comparerCurrent.BothModified); //Compare the _actions and dirty items in current folder. Collision is detected when //2 items in 2 collection have same relative path but different hashes. IEnumerable <SyncAction> conflictItems = from action in _actions join dirtyInCurrent in dirtyItemsInCurrent on action.RelativeFilePath equals dirtyInCurrent.RelativePath where !action.FileHash.Equals(dirtyInCurrent.HashCode) select action; foreach (SyncAction action in conflictItems) { action.ConflictResolution = ConflictResolution.DUPLICATE_RENAME; } IEnumerable <SyncAction> itemsToDelete = from action in _actions where action.ChangeType == ChangeType.DELETED select action; IEnumerable <SyncAction> itemsToCopyOver = from action in _actions where action.ChangeType == ChangeType.NEWLY_CREATED && !conflictItems.Contains(action) select action; IEnumerable <SyncAction> itemsToRename = from action in _actions where action.ChangeType == ChangeType.RENAMED && !conflictItems.Contains(action) select action; ConflictItems = conflictItems.ToList(); ItemsToCopyOver = itemsToCopyOver.ToList(); ItemsToDelete = itemsToDelete.ToList(); ItemsToRename = itemsToRename.ToList(); }
/// <summary> /// Generates SyncActions to be executed by other PC by comparing the metadata /// of current SyncSource and the metadata of other PC. /// </summary> private IList <SyncAction> GenerateActions() { //Metadata mdCurrent = UpdateSyncSourceMetadata(); //Metadata mdOther = mdProvider.Load(_job.SyncSource.ID, SourceOption.SOURCE_ID_NOT_EQUALS); FileMetaData mdCurrent = MetaDataProvider.GenerateFileMetadata( _job.SyncSource.Path, _job.SyncSource.ID, false, false); FileMetaData mdOldCurrent = mdProvider.LoadFileMetadata(_job.SyncSource.ID, SourceOption.SOURCE_ID_EQUALS); mdProvider.UpdateFileMetadata(mdOldCurrent, mdCurrent); FileMetaData mdOther = mdProvider.LoadFileMetadata(_job.SyncSource.ID, SourceOption.SOURCE_ID_NOT_EQUALS); //generate list of sync actions by comparing 2 metadata var differences = new FileMetaDataComparer(mdCurrent, mdOther); return(actProvider.Generate(mdCurrent.SourceId, differences.LeftOnly, differences.RightOnly, differences.BothModified)); }
private void Compare(FileMetaData left, FileMetaData right) { FileMetaDataItemComparer comparer = new FileMetaDataItemComparer(); var rightOnly = from i in right.MetaDataItems where !left.MetaDataItems.Contains(i, comparer) select i; var leftOnly = from i in left.MetaDataItems where !right.MetaDataItems.Contains(i, comparer) select i; var both = from l in left.MetaDataItems join r in right.MetaDataItems on l.RelativePath equals r.RelativePath where l.HashCode != r.HashCode select l; this.LeftOnly = new List<FileMetaDataItem>(leftOnly); this.RightOnly = new List<FileMetaDataItem>(rightOnly); this.BothModified = new List<FileMetaDataItem>(both); }
private void GeneratePreview(FileMetaData currentMetadata, FileMetaData oldCurrentMetadata) { //By comparing current metadata and the old metadata from previous sync of a sync folder //we could know the dirty items of the folder. var comparerCurrent = new FileMetaDataComparer(currentMetadata, oldCurrentMetadata); var dirtyItemsInCurrent = new List<FileMetaDataItem>(); dirtyItemsInCurrent.AddRange(comparerCurrent.LeftOnly); dirtyItemsInCurrent.AddRange(comparerCurrent.BothModified); //Compare the _actions and dirty items in current folder. Collision is detected when //2 items in 2 collection have same relative path but different hashes. IEnumerable<SyncAction> conflictItems = from action in _actions join dirtyInCurrent in dirtyItemsInCurrent on action.RelativeFilePath equals dirtyInCurrent.RelativePath where !action.FileHash.Equals(dirtyInCurrent.HashCode) select action; foreach (SyncAction action in conflictItems) action.ConflictResolution = ConflictResolution.DUPLICATE_RENAME; IEnumerable<SyncAction> itemsToDelete = from action in _actions where action.ChangeType == ChangeType.DELETED select action; IEnumerable<SyncAction> itemsToCopyOver = from action in _actions where action.ChangeType == ChangeType.NEWLY_CREATED && !conflictItems.Contains(action) select action; IEnumerable<SyncAction> itemsToRename = from action in _actions where action.ChangeType == ChangeType.RENAMED && !conflictItems.Contains(action) select action; ConflictItems = conflictItems.ToList(); ItemsToCopyOver = itemsToCopyOver.ToList(); ItemsToDelete = itemsToDelete.ToList(); ItemsToRename = itemsToRename.ToList(); }
private void Compare(FileMetaData left, FileMetaData right) { FileMetaDataItemComparer comparer = new FileMetaDataItemComparer(); var rightOnly = from i in right.MetaDataItems where !left.MetaDataItems.Contains(i, comparer) select i; var leftOnly = from i in left.MetaDataItems where !right.MetaDataItems.Contains(i, comparer) select i; var both = from l in left.MetaDataItems join r in right.MetaDataItems on l.RelativePath equals r.RelativePath where l.HashCode != r.HashCode select l; this.LeftOnly = new List <FileMetaDataItem>(leftOnly); this.RightOnly = new List <FileMetaDataItem>(rightOnly); this.BothModified = new List <FileMetaDataItem>(both); }
public FileMetaDataComparer(FileMetaData left, FileMetaData right) { Compare(left, right); }
public SyncPreviewResult(IList <SyncAction> actions, FileMetaData currentMetadata, FileMetaData oldCurrentMetadata, FileMetaData oldOtherMetadata) { this._actions = actions; GeneratePreview(currentMetadata, oldCurrentMetadata); }
public override bool UpdateFileMetadata(FileMetaData oldMetadata, FileMetaData newMetadata) { //Sort list of metadata items before search using linq oldMetadata.MetaDataItems.ToList().Sort(new FileMetaDataItemComparer()); newMetadata.MetaDataItems.ToList().Sort(new FileMetaDataItemComparer()); var mdComparer = new FileMetaDataComparer(oldMetadata, newMetadata); var db = new SQLiteAccess(Path.Combine(this.StoragePath, Configuration.DATABASE_NAME),false); using (SqliteConnection con = db.NewSQLiteConnection()) { if (con == null) throw new DatabaseException(String.Format(m_ResourceManager.GetString("err_somethingNotFound"), Path.Combine(this.StoragePath, Configuration.DATABASE_NAME))); var transaction = (SqliteTransaction)con.BeginTransaction(); try { this.Add(mdComparer.RightOnly.ToList(), con); this.Delete(mdComparer.LeftOnly.ToList(), con); this.Update(mdComparer.BothModified.ToList(), con); transaction.Commit(); } catch (Exception) { transaction.Rollback(); return false; } } return true; }
/// <summary> /// Add metadata infomation. /// </summary> /// <param name="mData">Metadata to be added.</param> /// <returns>true if added and saved successfully.</returns> public abstract bool Add(FileMetaData mData);
public override bool Add(FileMetaData mData) { return this.Add(mData.MetaDataItems); }
public SyncPreviewResult(IList<SyncAction> actions, FileMetaData currentMetadata, FileMetaData oldCurrentMetadata, FileMetaData oldOtherMetadata) { this._actions = actions; GeneratePreview(currentMetadata, oldCurrentMetadata); }
public Metadata(FileMetaData fileMetadata, FolderMetadata folderMetadata) { this.FileMetadata = fileMetadata; this.FolderMetadata = folderMetadata; }
public static FileMetaData GenerateFileMetadata(string fromPath, string id, bool excludeHidden, StatusCallbackDelegate statusCallback) { FileMetaData fileMetadata = new FileMetaData(id, fromPath); DirectoryInfo di = new DirectoryInfo(fromPath); AddDirectorySecurity(fromPath); FileInfo[] files = null; if (statusCallback != null) statusCallback("Reading files from: " + fromPath); files = di.GetFiles("*.*", SearchOption.AllDirectories); if (files == null) return new FileMetaData(id, fromPath); IEnumerable<FileInfo> noHiddenFiles = from file in files where excludeHidden ? !Files.FileUtils.IsFileHidden(file.FullName) : true select file; files = noHiddenFiles.ToArray<FileInfo>(); foreach (FileInfo f in files) { try { if (statusCallback != null) statusCallback(string.Format("Processing file: {0}", f.FullName)); fileMetadata.MetaDataItems.Add(new FileMetaDataItem(id, OneSync.Files.FileUtils.GetRelativePath(fromPath, f.FullName), Files.FileUtils.GetFileHash(f.FullName), f.LastWriteTime, (uint)0, (uint)0)); }catch(Exception){ } } return fileMetadata; }
/// <summary> /// /// </summary> /// <param name="oldItems"></param> /// <param name="newItems"></param> /// <returns></returns> public abstract bool UpdateFileMetadata(FileMetaData oldItems, FileMetaData newItems);
public override bool Add(FileMetaData mData) { return(this.Add(mData.MetaDataItems)); }
private bool UpdateFileMetadata(FileMetaData oldMetadata, FileMetaData newMetadata, SqliteConnection con) { //Sort list of metadata items before search using linq oldMetadata.MetaDataItems.ToList().Sort(new FileMetaDataItemComparer()); newMetadata.MetaDataItems.ToList().Sort(new FileMetaDataItemComparer()); //Get newly created items by comparing relative paths //newOnly is metadata item in current metadata but not in old one IEnumerable<FileMetaDataItem> newOnly = newMetadata.MetaDataItems.Where( @new => !oldMetadata.MetaDataItems.Contains(@new, new FileMetaDataItemComparer())); //Get deleted items IEnumerable<FileMetaDataItem> oldOnly = oldMetadata.MetaDataItems.Where( old => !newMetadata.MetaDataItems.Contains(old, new FileMetaDataItemComparer())); //get the items from 2 metadata with same relative paths but different hashes. IEnumerable<FileMetaDataItem> bothModified = newMetadata.MetaDataItems.SelectMany( @new => oldMetadata.MetaDataItems, (@new, old) => new {@new, old}).Where( @t => @[email protected]((@t.old).RelativePath) && !@[email protected](@t.old.HashCode)).Select(@t => @t.@new); try { this.Add(newOnly.ToList(), con); this.Delete(oldOnly.ToList(), con); this.Update(bothModified.ToList(), con); } catch (Exception) { return false; } return true; }
public override FileMetaData LoadFileMetadata(string currId, SourceOption option) { string opt = (option == SourceOption.SOURCE_ID_NOT_EQUALS) ? " <> " : " = "; var mData = new FileMetaData(currId, RootPath); var db = new SQLiteAccess(Path.Combine(this.StoragePath, Configuration.DATABASE_NAME),false); using (SqliteConnection con = db.NewSQLiteConnection()) { if (con == null) throw new DatabaseException(String.Format(m_ResourceManager.GetString("err_somethingNotFound"), Path.Combine(this.StoragePath, Configuration.DATABASE_NAME))); string cmdText = string.Format("SELECT * FROM {0} WHERE {1}{2} @sourceId", Configuration.TBL_METADATA, Configuration.COL_SOURCE_ID, opt); var paramList = new SqliteParameterCollection { new SqliteParameter("@sourceId", DbType.String) {Value = currId} }; db.ExecuteReader(cmdText, paramList, reader => mData.MetaDataItems.Add(new FileMetaDataItem( (string) reader[Configuration.COL_SOURCE_ID], (string) reader[Configuration.COL_RELATIVE_PATH], (string) reader[Configuration.COL_HASH_CODE], (DateTime) reader[Configuration.COL_LAST_MODIFIED_TIME], Convert.ToUInt32(reader[Configuration.COL_NTFS_ID1]), Convert.ToUInt32(reader[Configuration.COL_NTFS_ID2])))); } return mData; }