226 lines
7.5 KiB
C#
226 lines
7.5 KiB
C#
using System.Diagnostics;
|
|
using System.Runtime.InteropServices;
|
|
using System.Text;
|
|
using System.Text.Json;
|
|
using Common;
|
|
|
|
namespace RemoteServer;
|
|
|
|
public abstract class StateHelpBase(
|
|
RemoteSyncServer context,
|
|
SyncProcessStep step = SyncProcessStep.Connect
|
|
)
|
|
{
|
|
protected readonly RemoteSyncServer Context = context;
|
|
|
|
public readonly SyncProcessStep Step = step;
|
|
|
|
public SyncMsg CreateErrMsg(string Body)
|
|
{
|
|
return new SyncMsg
|
|
{
|
|
Body = Body,
|
|
Type = SyncMsgType.Error,
|
|
Step = Step
|
|
};
|
|
}
|
|
|
|
public SyncMsg CreateMsg(string body, SyncMsgType type = SyncMsgType.General)
|
|
{
|
|
return new SyncMsg
|
|
{
|
|
Body = body,
|
|
Type = type,
|
|
Step = Step
|
|
};
|
|
}
|
|
|
|
public bool ReceiveMsg(byte[] bytes)
|
|
{
|
|
var msg = Encoding.UTF8.GetString(bytes);
|
|
|
|
var syncMsg =
|
|
JsonSerializer.Deserialize<SyncMsg>(msg)
|
|
?? throw new NullReferenceException("msg is null");
|
|
if (syncMsg.Step != Step && syncMsg.Step != SyncProcessStep.Close)
|
|
{
|
|
throw new Exception("Sync step error!");
|
|
}
|
|
HandleMsg(syncMsg);
|
|
return true;
|
|
}
|
|
|
|
protected abstract void HandleMsg(SyncMsg msg);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 0. 链接验证
|
|
/// </summary>
|
|
/// <param name="context"></param>
|
|
public class ConnectAuthorityHelper(RemoteSyncServer context)
|
|
: StateHelpBase(context, SyncProcessStep.Connect)
|
|
{
|
|
protected override void HandleMsg(SyncMsg msg)
|
|
{
|
|
if (msg.Body == Context.Pwd)
|
|
{
|
|
var h = new DiffFileHelper(Context);
|
|
Context.SetStateHelpBase(h);
|
|
Context.Pipe.SendMsg(CreateMsg("RemoteServer: 密码验证成功!"));
|
|
}
|
|
else
|
|
{
|
|
throw new Exception("密码错误!");
|
|
}
|
|
}
|
|
}
|
|
|
|
public class DiffFileHelper(RemoteSyncServer context)
|
|
: StateHelpBase(context, SyncProcessStep.DiffFileAndPack)
|
|
{
|
|
protected override void HandleMsg(SyncMsg msg)
|
|
{
|
|
Context.SyncConfig = JsonSerializer.Deserialize<Config>(msg.Body);
|
|
|
|
var diffConfigs = new List<DirFileConfig>();
|
|
//文件对比
|
|
Context.NotNullSyncConfig.DirFileConfigs.ForEach(e =>
|
|
{
|
|
if (e.LocalDirInfo == null)
|
|
{
|
|
throw new NullReferenceException("RemoteServer: 发布的文件为空!--这个异常应该永远不会发生~");
|
|
}
|
|
else
|
|
{
|
|
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);
|
|
e.DiffDirInfo = e.LocalDirInfo.Diff(nd);
|
|
e.RemoteDirInfo = nd;
|
|
diffConfigs.Add(
|
|
new DirFileConfig { DiffDirInfo = e.DiffDirInfo, DirPath = e.DirPath }
|
|
);
|
|
}
|
|
});
|
|
var h = new UnPackAndReleaseHelper(Context);
|
|
Context.SetStateHelpBase(h);
|
|
//将对比结果发送到Local
|
|
Context.Pipe.SendMsg(CreateMsg(JsonSerializer.Serialize(diffConfigs)));
|
|
}
|
|
}
|
|
|
|
public class UnPackAndReleaseHelper(RemoteSyncServer context)
|
|
: StateHelpBase(context, SyncProcessStep.UploadAndUnpack)
|
|
{
|
|
public void UnPack()
|
|
{
|
|
FileDirOpForUnpack.FirstUnComparess(
|
|
Path.Combine(RemoteSyncServer.TempRootFile),
|
|
Context.NotNullSyncConfig.Id.ToString()
|
|
);
|
|
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);
|
|
}
|
|
});
|
|
}
|
|
|
|
protected override void HandleMsg(SyncMsg msg) { }
|
|
}
|
|
|
|
public class FinallyPublishHelper(RemoteSyncServer context)
|
|
: StateHelpBase(context, SyncProcessStep.Publish)
|
|
{
|
|
public void FinallyPublish()
|
|
{
|
|
// 发布数据库
|
|
if (Context.NotNullSyncConfig.IsDeployDb)
|
|
{
|
|
var arguments =
|
|
$" /Action:Publish /SourceFile:{RemoteSyncServer.TempRootFile}/{Context.NotNullSyncConfig.Id.ToString()}/{Context.NotNullSyncConfig.Id}.dacpac"
|
|
+ $" /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()
|
|
{
|
|
// 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("执行发布错误,错误信息参考上一条消息!");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Context.Pipe.SendMsg(CreateMsg("跳过数据库发布!")).Wait();
|
|
}
|
|
var DirFileOp = new FileDirOpForUnpack(
|
|
Path.Combine(RemoteSyncServer.TempRootFile, Context.NotNullSyncConfig.Id.ToString()),
|
|
Context.NotNullSyncConfig.RemoteRootPath
|
|
);
|
|
Context.NotNullSyncConfig.DirFileConfigs.ForEach(e =>
|
|
{
|
|
if (e.RemoteDirInfo != null && e.DiffDirInfo != null)
|
|
{
|
|
e.RemoteDirInfo.Combine(DirFileOp, e.DiffDirInfo, false, true);
|
|
}
|
|
});
|
|
|
|
Context.SetStateHelpBase(new NormalCloseHelper(Context));
|
|
Context.Pipe.SendMsg(CreateMsg("发布完成!")).Wait();
|
|
}
|
|
|
|
protected override void HandleMsg(SyncMsg msg) { }
|
|
}
|
|
|
|
public class NormalCloseHelper(RemoteSyncServer context)
|
|
: StateHelpBase(context, SyncProcessStep.Close)
|
|
{
|
|
protected override void HandleMsg(SyncMsg msg) { }
|
|
}
|