diff --git a/Server/Common/Dir.cs b/Server/Common/DirExtension.cs similarity index 96% rename from Server/Common/Dir.cs rename to Server/Common/DirExtension.cs index c32a0e8..b528408 100644 --- a/Server/Common/Dir.cs +++ b/Server/Common/DirExtension.cs @@ -2,12 +2,11 @@ namespace Common; public static class DirExtension { - - /// + /// /// 比较两个目录文件树是否相同,不相同返回差异部分,左侧是右侧的下一个版本,任何一个节点的nextop != null,即所有 /// 节点都会打上标记 /// 文件夹的 NextOp 只有新增和删除 - /// + /// /// /// /// 右侧版本接下来进行的操作 @@ -286,14 +285,15 @@ public static class DirExtension { bool filter(string path) { + var relativePath = path.Replace('\\', '/').Replace(thisDir.FormatedPath, ""); if (cherryPicks != null) { - return cherryPicks.Contains(path); + return cherryPicks.Contains(relativePath); } if (exculdes != null) { - return !exculdes.Contains(path); + return !exculdes.Contains(relativePath); } return true; } @@ -302,24 +302,27 @@ public static class DirExtension { throw new NotSupportedException("this dir is not empty."); } - string[] files = Directory.GetFiles(thisDir.FormatedPath); - string[] dirs = Directory.GetDirectories(thisDir.FormatedPath); - foreach (var file in files) + if (Directory.Exists(thisDir.FormatedPath)) { - if (filter(file)) + string[] files = Directory.GetFiles(thisDir.FormatedPath); + string[] dirs = Directory.GetDirectories(thisDir.FormatedPath); + foreach (var file in files) { - thisDir.Children.Add( - new File { Path = file, MTime = System.IO.File.GetLastWriteTime($"{file}") } - ); + if (filter(file)) + { + thisDir.Children.Add( + new File { Path = file, MTime = System.IO.File.GetLastWriteTime($"{file}") } + ); + } } - } - foreach (var dir in dirs) - { - if (filter(dir)) + foreach (var dir in dirs) { - var ndir = new Dir { Path = dir, Children = [] }; - ndir.ExtractInfo(); - thisDir.Children.Add(ndir); + if (filter(dir)) + { + var ndir = new Dir { Path = dir, Children = [] }; + ndir.ExtractInfo(cherryPicks, exculdes); + thisDir.Children.Add(ndir); + } } } } diff --git a/Server/Common/FileDirBase.cs b/Server/Common/FileDirBase.cs index 847df13..8fa825f 100644 --- a/Server/Common/FileDirBase.cs +++ b/Server/Common/FileDirBase.cs @@ -1,4 +1,6 @@ -namespace Common; +using System.Text.Json.Serialization; + +namespace Common; public enum DirOrFile { @@ -13,7 +15,10 @@ public enum NextOpType Del = 2 } -public abstract class AFileOrDir +[JsonDerivedType(typeof(AFileOrDir), typeDiscriminator: 1)] +[JsonDerivedType(typeof(File), typeDiscriminator: 2)] +[JsonDerivedType(typeof(Dir), typeDiscriminator: 3)] +public class AFileOrDir { public DirOrFile Type { get; set; } public NextOpType? NextOp { get; set; } @@ -33,7 +38,11 @@ public abstract class AFileOrDir get { return Path.Replace("\\", "/"); } set { Path = value; } } - public abstract bool IsEqual(AFileOrDir other); + + public bool IsEqual(AFileOrDir other) + { + return false; + } public static int Compare(AFileOrDir l, AFileOrDir r) { @@ -53,13 +62,14 @@ public abstract class AFileOrDir /// 文件的修改时间/ public class File : AFileOrDir { - public File() + public File() { Type = DirOrFile.File; } + public required DateTime MTime { get; set; } - public override bool IsEqual(AFileOrDir other) + public new bool IsEqual(AFileOrDir other) { if (other is not File otherFile) { @@ -83,9 +93,10 @@ public class Dir : AFileOrDir { Type = DirOrFile.Dir; } + public required List Children { get; set; } - public override bool IsEqual(AFileOrDir other) + public new bool IsEqual(AFileOrDir other) { if (other is not Dir otherDir) { diff --git a/Server/LocalServer/StateHelper.cs b/Server/LocalServer/StateHelper.cs index c1a5658..d31e499 100644 --- a/Server/LocalServer/StateHelper.cs +++ b/Server/LocalServer/StateHelper.cs @@ -2,6 +2,7 @@ using System.Diagnostics; using System.Runtime.InteropServices; using System.Text; using System.Text.Json; +using System.Text.Json.Serialization; using Common; namespace LocalServer; @@ -210,8 +211,11 @@ public class DiffFileAndPackHelper(LocalSyncServer context) e.LocalDirInfo.ExtractInfo(e.CherryPicks, e.Excludes); }); //将配置信息发送到remoteServer + var options = new JsonSerializerOptions { WriteIndented = true }; Context - .RemotePipe.SendMsg(CreateMsg(JsonSerializer.Serialize(Context.NotNullSyncConfig))) + .RemotePipe.SendMsg( + CreateMsg(JsonSerializer.Serialize(Context.NotNullSyncConfig, options)) + ) .Wait(); } @@ -275,12 +279,13 @@ public class DeployMSSqlHelper(LocalSyncServer context) if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { var arguments = - $" /Action:Extract /TargetFile:{LocalSyncServer.TempRootFile}/{Context.NotNullSyncConfig.Id.ToString()}/{Context.NotNullSyncConfig.Id.ToString()}.dacpac " - + $"/DiagnosticsFile:{LocalSyncServer.TempRootFile}/{Context.NotNullSyncConfig.Id.ToString()}/{Context.NotNullSyncConfig.Id.ToString()}.log " - + $"/p:ExtractAllTableData=false /p:VerifyExtraction=true /SourceServerName:{Context.NotNullSyncConfig.SrcDb.ServerName}" - + $"/SourceDatabaseName:{Context.NotNullSyncConfig.SrcDb.DatebaseName} /SourceUser:{Context.NotNullSyncConfig.SrcDb.User} " - + $"/SourcePassword:{Context.NotNullSyncConfig.SrcDb.Password} /SourceTrustServerCertificate:{Context.NotNullSyncConfig.SrcDb.TrustServerCertificate} " - + $"/p:ExtractReferencedServerScopedElements=False /p:IgnoreUserLoginMappings=True /p:IgnorePermissions=True "; + $" /Action:Extract /TargetFile:{LocalSyncServer.TempRootFile}/{Context.NotNullSyncConfig.Id.ToString()}/{Context.NotNullSyncConfig.Id.ToString()}.dacpac" + // 不要log file 了 + //+ $" /DiagnosticsFile:{LocalSyncServer.TempRootFile}/{Context.NotNullSyncConfig.Id.ToString()}/{Context.NotNullSyncConfig.Id.ToString()}.log" + + $" /p:ExtractAllTableData=false /p:VerifyExtraction=true /SourceServerName:{Context.NotNullSyncConfig.SrcDb.ServerName}" + + $" /SourceDatabaseName:{Context.NotNullSyncConfig.SrcDb.DatebaseName} /SourceUser:{Context.NotNullSyncConfig.SrcDb.User}" + + $" /SourcePassword:{Context.NotNullSyncConfig.SrcDb.Password} /SourceTrustServerCertificate:{Context.NotNullSyncConfig.SrcDb.TrustServerCertificate}" + + $" /p:ExtractReferencedServerScopedElements=False /p:IgnoreUserLoginMappings=True /p:IgnorePermissions=True"; if (Context.NotNullSyncConfig.SrcDb.SyncTablesData != null) { foreach (var t in Context.NotNullSyncConfig.SrcDb.SyncTablesData) @@ -343,7 +348,7 @@ public class UploadPackedHelper(LocalSyncServer context) Context .LocalPipe.UploadFile( Context.NotNullSyncConfig.RemoteUrl, - $"{LocalSyncServer.TempRootFile}/{Context.NotNullSyncConfig.Id}/{Context.NotNullSyncConfig.Id}.zip", + $"{LocalSyncServer.TempRootFile}/{Context.NotNullSyncConfig.Id}.zip", (double current) => { Context diff --git a/Server/RemoteServer/StateHelper.cs b/Server/RemoteServer/StateHelper.cs index 036eb32..7f2ae32 100644 --- a/Server/RemoteServer/StateHelper.cs +++ b/Server/RemoteServer/StateHelper.cs @@ -100,13 +100,13 @@ public class DiffFileHelper(RemoteSyncServer context) } else { - var nd = e.LocalDirInfo.Clone(); - nd.ResetRootPath( - Context.NotNullSyncConfig.LocalRootPath, - Context.NotNullSyncConfig.RemoteRootPath - ); + var nd = new Dir + { + Path = Context.NotNullSyncConfig.RemoteRootPath + e.DirPath, + Children = [] + }; nd.ExtractInfo(e.CherryPicks, e.Excludes); - e.DiffDirInfo = nd.Diff(nd); + e.DiffDirInfo = e.LocalDirInfo.Diff(nd); e.RemoteDirInfo = nd; diffConfigs.Add( new DirFileConfig { DiffDirInfo = e.DiffDirInfo, DirPath = e.DirPath } @@ -149,9 +149,9 @@ public class FinallyPublishHelper(RemoteSyncServer context) if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { var arguments = - $"/Action:Publish /SourceFile: {RemoteSyncServer.TempRootFile}/{Context.NotNullSyncConfig.Id}/{Context.NotNullSyncConfig.Id}.dacpac " - + $"/TargetServerName:{Context.NotNullSyncConfig.DstDb.ServerName} /TargetDatabaseName:{Context.NotNullSyncConfig.DstDb.DatebaseName}" - + $" /TargetUser:{Context.NotNullSyncConfig.DstDb.User} /TargetPassword:{Context.NotNullSyncConfig.DstDb.Password} /TargetTrustServerCertificate:True "; + $" /Action:Publish /SourceFile: {RemoteSyncServer.TempRootFile}/{Context.NotNullSyncConfig.Id}/{Context.NotNullSyncConfig.Id}.dacpac" + + $" /TargetServerName:{Context.NotNullSyncConfig.DstDb.ServerName} /TargetDatabaseName:{Context.NotNullSyncConfig.DstDb.DatebaseName}" + + $" /TargetUser:{Context.NotNullSyncConfig.DstDb.User} /TargetPassword:{Context.NotNullSyncConfig.DstDb.Password} /TargetTrustServerCertificate:True"; ProcessStartInfo startInfo = new() @@ -204,7 +204,7 @@ public class FinallyPublishHelper(RemoteSyncServer context) { if (e.RemoteDirInfo != null && e.DiffDirInfo != null) { - e.RemoteDirInfo.Combine(DirFileOp, e.DiffDirInfo,false,true); + e.RemoteDirInfo.Combine(DirFileOp, e.DiffDirInfo, false, true); } }); diff --git a/Server/ServerTest/PipeSeed.cs b/Server/ServerTest/PipeSeed.cs index bdabf7a..fc8125d 100644 --- a/Server/ServerTest/PipeSeed.cs +++ b/Server/ServerTest/PipeSeed.cs @@ -11,7 +11,7 @@ public class PipeSeed : IDisposable TestConfig = new Config { Name = "Test", - RemoteUrl = "D:/FileSyncTest", + RemoteUrl = "D:/FileSyncTest/dtemp", RemotePwd = "t123", IsDeployDb = true, IsDeployProject = true, diff --git a/Server/ServerTest/PipeTest.cs b/Server/ServerTest/PipeTest.cs index fc9673f..3723af0 100644 --- a/Server/ServerTest/PipeTest.cs +++ b/Server/ServerTest/PipeTest.cs @@ -13,46 +13,48 @@ public class PipeTest [Fact] public async void TestCase() { - // var p1 = new TestPipe(false, "1"); - // var x = Task.Run(async () => - // { - // var rs = p1.Work( - // (byte[] b) => - // { - // Console.WriteLine(b); - // return true; - // } - // ); - // await foreach (var r in rs) - // { - // Console.WriteLine(r); - // } - // }); - // //await p1.Close("sdf"); - // //await x; - // var p2 = new TestPipe(false, "2"); - // p1.Other = p2; - // p2.Other = p1; - // var p3 = new TestPipe(true, "3"); - // var p4 = new TestPipe(true, "4"); - // p3.Other = p4; - // p4.Other = p3; - // RemoteSyncServerFactory.NamePwd = [new Tuple("Test", "t123")]; - // var lf = new LocalSyncServerFactory(); - // lf.CreateLocalSyncServer(p2, "Test", p3); - // var rf = new RemoteSyncServerFactory(); - // rf.CreateRemoteSyncServer(p4, "Test"); - // var starter = new SyncMsg - // { - // Body = JsonSerializer.Serialize(new PipeSeed().TestConfig), - // Type = SyncMsgType.General, - // Step = SyncProcessStep.Connect - // }; - // await p1.SendMsg(starter); - // await x; - // if (p1.ErrResult != null) - // { - // Assert.Fail(p1.ErrResult); - // } + var p1 = new TestPipe(false, "1"); + var x = Task.Run(async () => + { + var rs = p1.Work( + (byte[] b) => + { + Console.WriteLine(b); + return true; + } + ); + await foreach (var r in rs) + { + Console.WriteLine(r); + } + }); + //await p1.Close("sdf"); + //await x; + var p2 = new TestPipe(false, "2"); + p1.Other = p2; + p2.Other = p1; + var p3 = new TestPipe(true, "3"); + var p4 = new TestPipe(true, "4"); + p3.Other = p4; + p4.Other = p3; + LocalSyncServer.TempRootFile = "D:/FileSyncTest/stemp"; + RemoteSyncServer.TempRootFile = "D:/FileSyncTest/dtemp"; + RemoteSyncServerFactory.NamePwd = [new Tuple("Test", "t123")]; + var lf = new LocalSyncServerFactory(); + lf.CreateLocalSyncServer(p2, "Test", p3); + var rf = new RemoteSyncServerFactory(); + rf.CreateRemoteSyncServer(p4, "Test"); + var starter = new SyncMsg + { + Body = JsonSerializer.Serialize(new PipeSeed().TestConfig), + Type = SyncMsgType.General, + Step = SyncProcessStep.Connect + }; + await p1.SendMsg(starter); + await x; + if (p1.ErrResult != null) + { + Assert.Fail(p1.ErrResult); + } } } diff --git a/Server/ServerTest/TestPipe.cs b/Server/ServerTest/TestPipe.cs index b2a1bb8..45cb20a 100644 --- a/Server/ServerTest/TestPipe.cs +++ b/Server/ServerTest/TestPipe.cs @@ -2,6 +2,7 @@ using System.Text; using System.Text.Json; using Common; +using RemoteServer; namespace ServerTest { @@ -25,14 +26,19 @@ namespace ServerTest } public override async Task UploadFile( - string filePath, string dst, + string filePath, Func progressCb ) { + dst = Path.Combine(RemoteSyncServer.TempRootFile, Path.GetFileName(filePath)); await Task.Run(() => { progressCb(100); + //if (!Directory.Exists(dst)) + //{ + // Directory.CreateDirectory(dst); + //} System.IO.File.Copy(filePath, dst, true); }); }