Преглед изворни кода

Bug 1802 – ComparisonDifference.Resolve method to process individual ComparisonDifference instances

https://winscp.net/tracker/1802

Source commit: 5a12c583d36365ec537cbc17ae575157439ddad9
Martin Prikryl пре 5 година
родитељ
комит
b3ee247b3d
2 измењених фајлова са 118 додато и 15 уклоњено
  1. 75 1
      dotnet/ComparisonDifference.cs
  2. 43 14
      dotnet/Session.cs

+ 75 - 1
dotnet/ComparisonDifference.cs

@@ -1,4 +1,5 @@
 using System;
+using System.IO;
 using System.Runtime.InteropServices;
 
 namespace WinSCP
@@ -44,8 +45,81 @@ namespace WinSCP
         public ComparisonFileInfo Local { get; internal set; }
         public ComparisonFileInfo Remote { get; internal set; }
 
-        internal ComparisonDifference()
+        internal ComparisonDifference(string localPath, string remotePath)
         {
+            _localPath = localPath;
+            _remotePath = remotePath;
         }
+
+        public FileOperationEventArgs Resolve(Session session, TransferOptions options = null)
+        {
+            if (session == null)
+            {
+                throw new ArgumentNullException(nameof(session));
+            }
+
+            switch (Action)
+            {
+                case SynchronizationAction.UploadNew:
+                case SynchronizationAction.UploadUpdate:
+                    {
+                        string remoteDirectory =
+                            RemotePath.TranslateLocalPathToRemote(Path.GetDirectoryName(Local.FileName), _localPath, _remotePath);
+                        if (!IsDirectory)
+                        {
+                            return session.PutFileToDirectory(Local.FileName, remoteDirectory, options: options);
+                        }
+                        else
+                        {
+                            session.PutEntryToDirectory(Local.FileName, remoteDirectory, options: options);
+                            return null;
+                        }
+                    }
+
+                case SynchronizationAction.DownloadNew:
+                case SynchronizationAction.DownloadUpdate:
+                    {
+                        string localDirectory =
+                            RemotePath.TranslateRemotePathToLocal(RemotePath.GetDirectoryName(Remote.FileName), _remotePath, _localPath);
+                        if (!IsDirectory)
+                        {
+                            return session.GetFileToDirectory(Remote.FileName, localDirectory, options: options);
+                        }
+                        else
+                        {
+                            session.GetEntryToDirectory(Remote.FileName, localDirectory, options: options);
+                            return null;
+                        }
+                    }
+
+                case SynchronizationAction.DeleteRemote:
+                    if (!IsDirectory)
+                    {
+                        return session.RemoveFile(Remote.FileName);
+                    }
+                    else
+                    {
+                        session.RemoveEntry(Remote.FileName);
+                        return null;
+                    }
+
+                case SynchronizationAction.DeleteLocal:
+                    if (!IsDirectory)
+                    {
+                        File.Delete(Local.FileName);
+                    }
+                    else
+                    {
+                        Directory.Delete(Local.FileName, true);
+                    }
+                    return null;
+
+                default:
+                    throw session.Logger.WriteException(new InvalidOperationException());
+            }
+        }
+
+        private readonly string _localPath;
+        private readonly string _remotePath;
     }
 }

+ 43 - 14
dotnet/Session.cs

@@ -790,22 +790,31 @@ namespace WinSCP
             // Not locking, locked in PutFiles (within PutFilesToDirectory)
             using (Logger.CreateCallstack())
             {
-                if (string.IsNullOrEmpty(localFilePath))
+                if (!File.Exists(localFilePath))
                 {
-                    throw Logger.WriteException(new ArgumentException("File to path cannot be empty", nameof(localFilePath)));
+                    throw Logger.WriteException(new FileNotFoundException($"File {localFilePath} does not exist", localFilePath));
                 }
 
-                if (!File.Exists(localFilePath))
+                TransferOperationResult operationResult = PutEntryToDirectory(localFilePath, remoteDirectory, remove, options);
+                return GetOnlyFileOperation(operationResult.Transfers);
+            }
+        }
+
+        internal TransferOperationResult PutEntryToDirectory(string localFilePath, string remoteDirectory, bool remove = false, TransferOptions options = null)
+        {
+            using (Logger.CreateCallstack())
+            {
+                if (string.IsNullOrEmpty(localFilePath))
                 {
-                    throw Logger.WriteException(new FileNotFoundException($"File {localFilePath} does not exist", localFilePath));
+                    throw Logger.WriteException(new ArgumentException("File to path cannot be empty", nameof(localFilePath)));
                 }
+
                 string localDirectory = Path.GetDirectoryName(localFilePath);
                 string filemask = RemotePath.EscapeFileMask(Path.GetFileName(localFilePath));
 
-                TransferOperationResult operationResult =
-                    PutFilesToDirectory(localDirectory, remoteDirectory, filemask, remove, options);
+                TransferOperationResult operationResult = PutFilesToDirectory(localDirectory, remoteDirectory, filemask, remove, options);
                 operationResult.Check();
-                return GetOnlyFileOperation(operationResult.Transfers);
+                return operationResult;
             }
         }
 
@@ -920,6 +929,17 @@ namespace WinSCP
         public TransferEventArgs GetFileToDirectory(string remoteFilePath, string localDirectory, bool remove = false, TransferOptions options = null)
         {
             using (Logger.CreateCallstackAndLock())
+            {
+                const string additionalParams = "-onlyfile";
+                TransferOperationResult operationResult = GetEntryToDirectory(remoteFilePath, localDirectory, remove, options, additionalParams);
+                return GetOnlyFileOperation(operationResult.Transfers);
+            }
+        }
+
+        internal TransferOperationResult GetEntryToDirectory(
+            string remoteFilePath, string localDirectory, bool remove = false, TransferOptions options = null, string additionalParams = null)
+        {
+            using (Logger.CreateCallstack())
             {
                 if (string.IsNullOrEmpty(remoteFilePath))
                 {
@@ -930,9 +950,9 @@ namespace WinSCP
                 string filemask = RemotePath.EscapeFileMask(RemotePath.GetFileName(remoteFilePath));
 
                 TransferOperationResult operationResult =
-                    DoGetFilesToDirectory(remoteDirectory, localDirectory, filemask, remove, options, "-onlyfile");
+                    DoGetFilesToDirectory(remoteDirectory, localDirectory, filemask, remove, options, additionalParams ?? string.Empty);
                 operationResult.Check();
-                return GetOnlyFileOperation(operationResult.Transfers);
+                return operationResult;
             }
         }
 
@@ -988,6 +1008,15 @@ namespace WinSCP
         public RemovalEventArgs RemoveFile(string path)
         {
             using (Logger.CreateCallstackAndLock())
+            {
+                RemovalOperationResult operationResult = RemoveEntry(path, "-onlyfile");
+                return GetOnlyFileOperation(operationResult.Removals);
+            }
+        }
+
+        internal RemovalOperationResult RemoveEntry(string path, string additionalParams = null)
+        {
+            using (Logger.CreateCallstack())
             {
                 if (string.IsNullOrEmpty(path))
                 {
@@ -1002,9 +1031,9 @@ namespace WinSCP
                 }
                 path = RemotePath.Combine(remoteDirectory, filemask);
 
-                RemovalOperationResult operationResult = DoRemoveFiles(path, "-onlyfile");
+                RemovalOperationResult operationResult = DoRemoveFiles(path, additionalParams ?? string.Empty);
                 operationResult.Check();
-                return GetOnlyFileOperation(operationResult.Removals);
+                return operationResult;
             }
         }
 
@@ -1176,11 +1205,11 @@ namespace WinSCP
             {
                 DoSynchronizeDirectories(mode, localPath, remotePath, removeFiles, mirror, criteria, options, "-preview");
 
-                return ReadCompareDirectories();
+                return ReadCompareDirectories(localPath, remotePath);
             }
         }
 
-        private ComparisonDifferenceCollection ReadCompareDirectories()
+        private ComparisonDifferenceCollection ReadCompareDirectories(string localPath, string remotePath)
         {
             using (Logger.CreateCallstack())
             {
@@ -1192,7 +1221,7 @@ namespace WinSCP
                     {
                         using (ElementLogReader differenceReader = groupReader.CreateLogReader())
                         {
-                            ComparisonDifference difference = new ComparisonDifference();
+                            ComparisonDifference difference = new ComparisonDifference(localPath, remotePath);
                             ComparisonFileInfo current = null;
 
                             while (differenceReader.Read(0))