FileSqlServerSync/Server/RemoteServer/StateHelper.cs

226 lines
7.5 KiB
C#
Raw Normal View History

2024-09-05 01:59:57 +00:00
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Text;
2024-09-05 01:59:57 +00:00
using System.Text.Json;
using Common;
namespace RemoteServer;
public abstract class StateHelpBase(
RemoteSyncServer context,
2024-09-05 01:59:57 +00:00
SyncProcessStep step = SyncProcessStep.Connect
)
{
protected readonly RemoteSyncServer Context = context;
2024-09-05 01:59:57 +00:00
public readonly SyncProcessStep Step = step;
2024-09-05 01:59:57 +00:00
public SyncMsg CreateErrMsg(string Body)
{
return new SyncMsg
{
Body = Body,
Type = SyncMsgType.Error,
Step = Step
};
2024-09-05 01:59:57 +00:00
}
public SyncMsg CreateMsg(string body, SyncMsgType type = SyncMsgType.General)
{
return new SyncMsg
{
Body = body,
Type = type,
Step = Step
};
2024-09-05 01:59:57 +00:00
}
public bool ReceiveMsg(byte[] bytes)
2024-09-05 01:59:57 +00:00
{
var msg = Encoding.UTF8.GetString(bytes);
2024-09-05 01:59:57 +00:00
var syncMsg =
JsonSerializer.Deserialize<SyncMsg>(msg)
?? throw new NullReferenceException("msg is null");
if (syncMsg.Step != Step && syncMsg.Step != SyncProcessStep.Close)
2024-09-05 01:59:57 +00:00
{
throw new Exception("Sync step error!");
}
HandleMsg(syncMsg);
return true;
2024-09-05 01:59:57 +00:00
}
protected abstract void HandleMsg(SyncMsg msg);
2024-09-05 01:59:57 +00:00
}
/// <summary>
/// 0. 链接验证
/// </summary>
/// <param name="context"></param>
public class ConnectAuthorityHelper(RemoteSyncServer context)
2024-09-05 01:59:57 +00:00
: StateHelpBase(context, SyncProcessStep.Connect)
{
protected override void HandleMsg(SyncMsg msg)
2024-09-05 01:59:57 +00:00
{
if (msg.Body == Context.Pwd)
2024-09-05 01:59:57 +00:00
{
var h = new DiffFileHelper(Context);
Context.SetStateHelpBase(h);
Context.Pipe.SendMsg(CreateMsg("RemoteServer: 密码验证成功!"));
}
else
{
throw new Exception("密码错误!");
}
2024-09-05 01:59:57 +00:00
}
}
public class DiffFileHelper(RemoteSyncServer context)
: StateHelpBase(context, SyncProcessStep.DiffFileAndPack)
2024-09-05 01:59:57 +00:00
{
protected override void HandleMsg(SyncMsg msg)
2024-09-05 01:59:57 +00:00
{
Context.SyncConfig = JsonSerializer.Deserialize<Config>(msg.Body);
2024-09-22 05:27:52 +00:00
var diffConfigs = new List<DirFileConfig>();
//文件对比
Context.NotNullSyncConfig.DirFileConfigs.ForEach(e =>
2024-09-05 01:59:57 +00:00
{
if (e.LocalDirInfo == null)
2024-09-05 01:59:57 +00:00
{
throw new NullReferenceException("RemoteServer: 发布的文件为空!--这个异常应该永远不会发生~");
2024-09-05 01:59:57 +00:00
}
else
{
2024-09-24 09:46:52 +00:00
var nd = new Dir
{
Path = Context.NotNullSyncConfig.RemoteRootPath + e.DirPath,
Children = []
};
nd.ExtractInfo(e.CherryPicks, e.Excludes);
var nl = e.LocalDirInfo.Clone();
nl.ResetRootPath(
Context.NotNullSyncConfig.LocalRootPath,
Context.NotNullSyncConfig.RemoteRootPath
);
//var x = JsonSerializer.Serialize(nd);
//var x2 = JsonSerializer.Serialize(nl);
2024-09-24 09:46:52 +00:00
e.DiffDirInfo = e.LocalDirInfo.Diff(nd);
e.RemoteDirInfo = nd;
diffConfigs.Add(
new DirFileConfig { DiffDirInfo = e.DiffDirInfo, DirPath = e.DirPath }
2024-09-22 05:27:52 +00:00
);
2024-09-05 01:59:57 +00:00
}
});
var h = new UnPackAndReleaseHelper(Context);
Context.SetStateHelpBase(h);
//将对比结果发送到Local
Context.Pipe.SendMsg(CreateMsg(JsonSerializer.Serialize(diffConfigs)));
2024-09-22 05:27:52 +00:00
}
}
public class UnPackAndReleaseHelper(RemoteSyncServer context)
: StateHelpBase(context, SyncProcessStep.UploadAndUnpack)
{
public void UnPack()
{
FileDirOpForUnpack.FirstUnComparess(
Path.Combine(RemoteSyncServer.TempRootFile),
2024-09-22 05:27:52 +00:00
Context.NotNullSyncConfig.Id.ToString()
);
2024-09-22 05:27:52 +00:00
Context.Pipe.SendMsg(CreateMsg("解压完成!")).Wait();
var h = new FinallyPublishHelper(Context);
Context.SetStateHelpBase(h);
Context.Pipe.SendMsg(h.CreateMsg("将要发布数据库,可能时间会较长!")).Wait();
Task.Run(() =>
{
try
{
h.FinallyPublish();
}
catch (Exception e)
{
Context.Close(e.Message);
}
});
2024-09-05 01:59:57 +00:00
}
2024-09-22 05:27:52 +00:00
protected override void HandleMsg(SyncMsg msg) { }
2024-09-05 01:59:57 +00:00
}
2024-09-22 05:27:52 +00:00
public class FinallyPublishHelper(RemoteSyncServer context)
: StateHelpBase(context, SyncProcessStep.Publish)
2024-09-05 01:59:57 +00:00
{
2024-09-22 05:27:52 +00:00
public void FinallyPublish()
2024-09-05 01:59:57 +00:00
{
2024-09-22 05:27:52 +00:00
// 发布数据库
if (Context.NotNullSyncConfig.IsDeployDb)
{
var arguments =
$" /Action:Publish /SourceFile:{RemoteSyncServer.TempRootFile}/{Context.NotNullSyncConfig.Id.ToString()}/{Context.NotNullSyncConfig.Id}.dacpac"
2024-10-28 09:28:18 +00:00
+ $" /TargetServerName:{Context.NotNullSyncConfig.DstDb.ServerName} /TargetDatabaseName:{Context.NotNullSyncConfig.DstDb.DatabaseName}"
+ $" /TargetUser:{Context.NotNullSyncConfig.DstDb.User} /TargetPassword:{Context.NotNullSyncConfig.DstDb.Password} /TargetTrustServerCertificate:True";
//Context
// .Pipe.SendMsg(CreateMsg($"发布脚本为: {RemoteSyncServer.SqlPackageAbPath} {arguments}"))
// .Wait();
ProcessStartInfo startInfo =
new()
2024-09-22 05:27:52 +00:00
{
// StandardOutputEncoding = System.Text.Encoding.UTF8,
Arguments = arguments,
FileName = RemoteSyncServer.SqlPackageAbPath, // The command to execute (can be any command line tool)
// The arguments to pass to the command (e.g., list directory contents)
RedirectStandardOutput = true, // Redirect the standard output to a string
UseShellExecute = false, // Do not use the shell to execute the command
CreateNoWindow = true // Do not create a new window for the command
};
using Process process = new() { StartInfo = startInfo };
// Start the process
process.Start();
// Read the output from the process
string output = process.StandardOutput.ReadToEnd();
// Wait for the process to exit
process.WaitForExit();
if (process.ExitCode == 0)
{
Context.Pipe.SendMsg(CreateMsg("数据库发布成功!")).Wait();
}
else
{
Context.Pipe.SendMsg(CreateErrMsg(output)).Wait();
throw new Exception("执行发布错误,错误信息参考上一条消息!");
}
2024-09-22 05:27:52 +00:00
}
else
{
Context.Pipe.SendMsg(CreateMsg("跳过数据库发布!")).Wait();
}
var DirFileOp = new FileDirOpForUnpack(
Path.Combine(RemoteSyncServer.TempRootFile, Context.NotNullSyncConfig.Id.ToString()),
2024-09-22 05:27:52 +00:00
Context.NotNullSyncConfig.RemoteRootPath
);
Context.NotNullSyncConfig.DirFileConfigs.ForEach(e =>
2024-09-22 05:27:52 +00:00
{
if (e.RemoteDirInfo != null && e.DiffDirInfo != null)
{
2024-09-24 09:46:52 +00:00
e.RemoteDirInfo.Combine(DirFileOp, e.DiffDirInfo, false, true);
}
});
2024-09-22 05:27:52 +00:00
Context.SetStateHelpBase(new NormalCloseHelper(Context));
2024-09-22 05:27:52 +00:00
Context.Pipe.SendMsg(CreateMsg("发布完成!")).Wait();
2024-09-05 01:59:57 +00:00
}
2024-09-22 05:27:52 +00:00
protected override void HandleMsg(SyncMsg msg) { }
}
public class NormalCloseHelper(RemoteSyncServer context)
: StateHelpBase(context, SyncProcessStep.Close)
{
protected override void HandleMsg(SyncMsg msg) { }
}