using MySqlConnector; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Dapper; using CliFx; using CliFx.Infrastructure; using CliFx.Attributes; using System.Data; using System.Data.Common; using Chenfeng.MES.Archiver.Core; using Chenfeng.MES.Archiver.Data; namespace Chenfeng.MES.Archiver.Commands { [Command("copy")] public class CopyTableCommand : ICommand, IArchiveReader { [CommandOption("connection", Description = "数据库连接")] public string Connection { get; set; } = ""; public string TableSuffix { get; set; } = "new"; public DbConnection? Db { get; private set; } public Action Print { get; set; } = (text) => { }; [CommandOption("legacy", Description = "旧版MES")] public bool Legacy { get; set; } = false; [CommandOption("replace", Description = "替换表")] public bool Replace { get; set; } = false; [CommandOption("restore", Description = "回复表")] public bool Restore { get; set; } = false; [CommandOption("rm-backup", Description = "删除备份表")] public bool RemoveBackup { get; set; } [CommandOption("timeout", Description = "sql命令超时时间")] public int Timeout { get; set; } = 3; [CommandOption("script", Description = "是否生成执行脚本")] public bool Script { get; set; } [CommandOption("verbose", 'v', Description = "显示sql")] public bool Verbose { get; set; } public ValueTask ExecuteAsync(IConsole console) { Print = (text) => console.Output.WriteLine($"{DateTime.Now.ToLongTimeString()} {text}"); var starMonth = DateTime.Now.AddMonths(-12).ToString("yyyyMM"); SqlMapper.Settings.CommandTimeout = 60 * Timeout; console.Output.WriteLine((Legacy ? "旧" : "新") + "版数据库"); try { if (this.Connection.Length > 0) { var connBuilder = new MySqlConnectionStringBuilder(this.Connection); connBuilder.SslMode = MySqlSslMode.None; connBuilder.CharacterSet = "utf8"; Db = new MySqlConnection(connBuilder.ConnectionString); } Db?.Open(); if (Legacy) { TableQueryHelper.MesLegacyTables(this, starMonth); } else { TableQueryHelper.MesTables(this, starMonth); } if (Db!=null && sqlScripts.Length>0) { var sql = "set foreign_key_checks = 0;" + sqlScripts.ToString() + "set foreign_key_checks = 1;"; if (Verbose) { Print(sql); } Db.Execute(sql); } if (Script) { if (Directory.Exists("./scripts") == false) { Directory.CreateDirectory("./scripts"); } using (var file = File.OpenWrite($"./scripts/mes{(Legacy ? "-legacy" : "")}-table.sql")) { using (var writer = new StreamWriter(file)) { writer.Write(sqlScripts); } } } Print("操作成功"); } catch (Exception ex) { console.Output.WriteLine(ex.ToString()); } finally { Db?.Close(); } return default; } public void ExecuteData(string table, string where, object param) { if (ExecuteBefore(table)) { ExecuteSql($"INSERT INTO `{TableDic[table]}` SELECT * FROM `{table}` WHERE {where}", param); } } public void ExecuteChildData(string table, string parentTable, string condition) { if (ExecuteBefore(table)) { ExecuteSql($"INSERT INTO `{TableDic[table]}` SELECT child.* FROM `{TableDic[parentTable]}` parent join `{table}` child on {condition} "); } } private bool ExecuteBefore(string table) { if (RemoveBackup) { ExecuteSql($"DROP TABLE IF EXISTS `{table}_bak`", Execute: false); } else if (Restore) { ExecuteSql($"DROP TABLE IF EXISTS `{table}`", Execute: false); ExecuteSql($"RENAME TABLE `{table}_bak` TO `{table}`", Execute: false); } else if (Replace) { ExecuteSql($"RENAME TABLE `{table}` TO `{table}_bak`", Execute: false); ExecuteSql($"RENAME TABLE `{TableDic[table]}` TO `{table}`", Execute: false); } else { ExecuteSql($"DROP TABLE IF EXISTS `{TableDic[table]}`"); ExecuteSql($"CREATE TABLE `{TableDic[table]}` LIKE `{table}`"); // IF NOT EXISTS Print(TableDic[table] + " 创建完成"); return true; } return false; } private StringBuilder sqlScripts = new StringBuilder(); private void ExecuteSql(string sql, object? param = null, bool Execute = true) { if (Execute) { Db?.Execute(sql, param); } if (Script || Execute == false) { var fullSql = sql + ";"; if (param != null) { foreach (var property in param.GetType().GetProperties()) { var val = property.GetValue(param)?.ToString(); fullSql = fullSql.Replace("@" + property.Name, val); } } sqlScripts.AppendLine(fullSql); } } public Dictionary TableDic { get; set; } = new Dictionary(); public void Step(Action action, params string[] tables) { var list = tables.Select(table => new { Table = table, NewTable = table + "_" + this.TableSuffix }); foreach (var item in list) { TableDic[item.Table] = item.NewTable; action(item.Table); } } } }