You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
459 lines
17 KiB
459 lines
17 KiB
using MySql.Data.MySqlClient;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Data;
|
|
using System.Text;
|
|
using System.Windows.Forms;
|
|
using System.IO;
|
|
|
|
namespace Tiobon.Core.OPS.Tool.OPS.Tool.View
|
|
{
|
|
public partial class Frm_DbExport : Form
|
|
{
|
|
#region 初始化
|
|
string m_ConnStr = "";
|
|
public Frm_DbExport(string connStr)
|
|
{
|
|
InitializeComponent();
|
|
m_ConnStr = connStr;
|
|
LoadTables();
|
|
LoadConf();
|
|
}
|
|
|
|
private void Form_DbExport_Load(object sender, EventArgs e)
|
|
{
|
|
timer_Main.Start();
|
|
}
|
|
#endregion
|
|
|
|
#region 选择文件路径
|
|
string m_FileName = "";
|
|
private void btn_select_Click(object sender, EventArgs e)
|
|
{
|
|
using (FolderBrowserDialog path = new FolderBrowserDialog())
|
|
{
|
|
if (path.ShowDialog() == DialogResult.OK)
|
|
{
|
|
if (System.IO.File.Exists($"{ path.SelectedPath}\\hdis_{DateTime.Now.ToString("yyyy_MM_dd")}.sql"))
|
|
{
|
|
if (MessageBox.Show("文件已存在,是否覆盖?", "警告", MessageBoxButtons.YesNo, MessageBoxIcon.Warning) == DialogResult.No)
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
this.txt_fname.Text = $"{ path.SelectedPath}\\hdis_{DateTime.Now.ToString("yyyy_MM_dd")}.sql";//返回文件的完整路径
|
|
}
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
#region 日志操作
|
|
private static List<string> m_LogsTemp = new List<string>();
|
|
private void timer_Main_Tick(object sender, EventArgs e)
|
|
{
|
|
try
|
|
{
|
|
lock (m_Logs)
|
|
{
|
|
m_LogsTemp.Clear();
|
|
m_Logs.ForEach(log => m_LogsTemp.Add(log));
|
|
m_Logs.Clear();
|
|
}
|
|
|
|
if (m_LogsTemp.Count > 0)
|
|
{
|
|
if (this.lb_Logger.Items.Count > 2000)
|
|
this.lb_Logger.Items.Clear();
|
|
m_LogsTemp.ForEach(log => this.lb_Logger.Items.Add(log));
|
|
this.lb_Logger.TopIndex = this.lb_Logger.Items.Count - 1;
|
|
}
|
|
}
|
|
catch { }
|
|
}
|
|
private static List<string> m_Logs = new List<string>();
|
|
private void SendLog(string oprator, string msg)
|
|
{
|
|
lock (m_Logs)
|
|
{
|
|
if (string.IsNullOrEmpty(oprator))
|
|
m_Logs.Add($"{DateTime.Now.ToString("HH:mm:ss")} {msg}");
|
|
else
|
|
m_Logs.Add($"{DateTime.Now.ToString("HH:mm:ss")} [{oprator}] {msg}");
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
#region 加载表名
|
|
Dictionary<string, List<string>> m_Tables = new Dictionary<string, List<string>>();
|
|
private void LoadTables()
|
|
{
|
|
try
|
|
{
|
|
m_Tables.Clear();
|
|
string sql = $"SELECT * FROM INFORMATION_SCHEMA.`COLUMNS` C WHERE C.TABLE_SCHEMA = 'hdis';";
|
|
DataTable dt = MySqlHelper.ExecuteDataset(m_ConnStr, sql).Tables[0];
|
|
foreach (DataRow dr in dt.Rows)
|
|
{
|
|
if (!m_Tables.ContainsKey(dr["TABLE_NAME"].ToString()))
|
|
{
|
|
m_Tables.Add(dr["TABLE_NAME"].ToString(), new List<string>
|
|
{
|
|
dr["COLUMN_NAME"].ToString()
|
|
});
|
|
treeView_Main.Nodes[0].Nodes.Add(dr["TABLE_NAME"].ToString());
|
|
}
|
|
else
|
|
{
|
|
m_Tables[dr["TABLE_NAME"].ToString()].Add(dr["COLUMN_NAME"].ToString());
|
|
}
|
|
}
|
|
treeView_Main.ExpandAll();
|
|
foreach (TreeNode node in treeView_Main.Nodes[0].Nodes)
|
|
{
|
|
node.Checked = true;
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
MessageBox.Show("读取数据库结构失败:" + ex.Message);
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
#region 选中节点
|
|
private void treeView_Main_BeforeCheck(object sender, TreeViewCancelEventArgs e)
|
|
{
|
|
TreeViewCheck.CheckControl(e);
|
|
}
|
|
#endregion
|
|
|
|
#region 导出
|
|
List<string> tabels = new List<string>();
|
|
private void btn_Export_Click(object sender, EventArgs e)
|
|
{
|
|
m_FileName = this.txt_fname.Text;
|
|
if (m_FileName == "")
|
|
return;
|
|
if (b_In)
|
|
{
|
|
return;
|
|
}
|
|
tabels.Clear();
|
|
foreach (TreeNode node in treeView_Main.Nodes[0].Nodes)
|
|
{
|
|
if (node.Checked)
|
|
{
|
|
tabels.Add(node.Text);
|
|
}
|
|
}
|
|
|
|
if (tabels.Count > 0)
|
|
{
|
|
System.Threading.Thread th = new System.Threading.Thread(Export);
|
|
th.Start();
|
|
}
|
|
}
|
|
bool b_In = false;
|
|
object m_Lock = new object();
|
|
private void Export()
|
|
{
|
|
lock (m_Lock)
|
|
{
|
|
if (b_In)
|
|
{
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
b_In = true;
|
|
}
|
|
}
|
|
DateTime dtStart = DateTime.Now;
|
|
try
|
|
{
|
|
SendLog("", "共有表 " + tabels.Count);
|
|
|
|
if (File.Exists(m_FileName))
|
|
{
|
|
File.Delete(m_FileName);
|
|
}
|
|
int tcount = 0;
|
|
StringBuilder sb = new StringBuilder();
|
|
sb.AppendLine("SET FOREIGN_KEY_CHECKS = 0;");
|
|
tabels.ForEach(tabelname =>
|
|
{
|
|
SetTotal(tabels.Count, ++tcount);
|
|
sb.AppendLine($"-- 正在导出 表 hdis.{tabelname} 结构");
|
|
SendLog("", $"-- 正在导出 表 hdis.{tabelname} 结构");
|
|
//删除原表
|
|
//sb.AppendLine($"DROP TABLE IF EXISTS `{tabelname}`;");
|
|
|
|
//导出表结构
|
|
sb.AppendLine($"{MySqlHelper.ExecuteDataset(m_ConnStr, $"SHOW CREATE TABLE `hdis`.`{tabelname}`;").Tables[0].Rows[0]["Create Table"].ToString()};");
|
|
sb.AppendLine();
|
|
|
|
//判断配置
|
|
string strWhere = string.Empty;
|
|
if (m_DBExportConf != null && m_DBExportConf.Content != null)
|
|
{
|
|
if (m_DBExportConf.Content.Except != null && !m_DBExportConf.Content.Except.Contains(tabelname)
|
|
&& m_DBExportConf.Content.Limit != null && !m_DBExportConf.Content.Limit.Contains(tabelname)
|
|
&& m_DBExportConf.Content.All != null && !m_DBExportConf.Content.All.Contains(tabelname))
|
|
{
|
|
//只导出表结构不导出数据
|
|
WriteToFile($"{sb.ToString()}");
|
|
sb.Clear();
|
|
SendLog("", $"表 {tabelname} [未配置] 只导出结构不导出数据");
|
|
return;
|
|
}
|
|
|
|
if (m_DBExportConf.Content.Except != null && m_DBExportConf.Content.Except.Contains(tabelname))
|
|
{
|
|
//只导出表结构不导出数据
|
|
WriteToFile($"{sb.ToString()}");
|
|
sb.Clear();
|
|
SendLog("", $"表 {tabelname} 只导出结构不导出数据");
|
|
return;
|
|
}
|
|
|
|
if (m_DBExportConf.Content.Limit != null && m_DBExportConf.Content.Limit.Contains(tabelname))
|
|
{
|
|
//导出规定时间内的数据,包含create_time字段
|
|
if (m_Tables[tabelname].Contains("create_time"))
|
|
{
|
|
SendLog("", $"表 {tabelname} 只导出 {m_DBExportConf.LimitTime} 天以内的数据");
|
|
strWhere = $" where create_time >= '{DateTime.Now.AddDays(m_DBExportConf.LimitTime * -1).ToString("yyyy-MM-dd HH:mm:ss")}'";
|
|
}
|
|
}
|
|
}
|
|
|
|
//导出数据
|
|
sb.AppendLine($"-- 正在导出 表 hdis.{tabelname} 数据");
|
|
int rows = int.Parse(MySqlHelper.ExecuteScalar(m_ConnStr, $"SELECT COUNT(0) FROM `hdis`.`{tabelname}`{strWhere};").ToString());
|
|
SendLog("", $"-- 正在导出 表 hdis.{tabelname} 数据,共有数据 {rows}");
|
|
|
|
int sum = 0;
|
|
using (MySqlDataReader reader = MySqlHelper.ExecuteReader(m_ConnStr, $"SELECT * FROM `hdis`.`{tabelname}`{strWhere};"))
|
|
{
|
|
if (reader.HasRows)
|
|
{
|
|
//字段类型
|
|
Dictionary<int, string> dic = new Dictionary<int, string>();
|
|
|
|
//添加字段
|
|
//sb.AppendLine($"DELETE FROM `{tabelname}`;");
|
|
|
|
StringBuilder sb_insert = new StringBuilder();
|
|
sb_insert.Append($"INSERT INTO `{tabelname}` (");
|
|
for (int i = 0; i < reader.FieldCount; ++i)
|
|
{
|
|
sb_insert.Append($"`{reader.GetName(i)}`");
|
|
if (i != reader.FieldCount - 1)
|
|
sb_insert.Append(", ");
|
|
|
|
dic.Add(i, reader.GetDataTypeName(i));
|
|
}
|
|
sb_insert.Append(") VALUES");
|
|
|
|
sb_insert.AppendLine();
|
|
//表开始
|
|
WriteToFile($"{sb.ToString()}");
|
|
sb.Clear();
|
|
|
|
int index = 0;
|
|
//添加数据
|
|
while (reader.Read())
|
|
{
|
|
sum++;
|
|
sb.Append("\t(");
|
|
for (int i = 0; i < reader.FieldCount; ++i)
|
|
{
|
|
sb.Append($"{ConvertData(reader[i], dic[i])}");
|
|
if (i != reader.FieldCount - 1)
|
|
sb.Append(", ");
|
|
}
|
|
sb.Append(")");
|
|
//500行数据入库一次
|
|
if (index++ >= 500)
|
|
{
|
|
sb.Append(";");
|
|
|
|
sb.AppendLine();
|
|
sb.AppendLine();
|
|
WriteToFile($"{sb_insert.ToString()}{sb.ToString()}");
|
|
sb.Clear();
|
|
index = 0;
|
|
continue;
|
|
}
|
|
//1024KB为一组插入语句
|
|
if (sb.Length >= 100 * 1024)
|
|
{
|
|
sb.Append(";");
|
|
sb.AppendLine();
|
|
sb.AppendLine();
|
|
WriteToFile($"{sb_insert.ToString()}{sb.ToString()}");
|
|
sb.Clear();
|
|
index = 0;
|
|
continue;
|
|
}
|
|
if (sum != rows)
|
|
sb.Append(",");
|
|
else
|
|
sb.Append(";");
|
|
|
|
sb.AppendLine();
|
|
}
|
|
|
|
//表结束
|
|
if (sb.Length > 0)
|
|
{
|
|
sb.AppendLine();
|
|
WriteToFile($"{sb_insert.ToString()}{sb.ToString()}");
|
|
sb.Clear();
|
|
index = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
sb.AppendLine();
|
|
});
|
|
sb.AppendLine("SET FOREIGN_KEY_CHECKS = 1;");
|
|
if (sb.Length > 0)
|
|
WriteToFile(sb.ToString());
|
|
|
|
DateTime dtEnd = DateTime.Now;
|
|
SendLog("", $"导出数据完毕,耗时 {(int)((dtEnd - dtStart).TotalSeconds / 60)}:{(int)((dtEnd - dtStart).TotalSeconds % 60)}");
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
SendLog("", "导出数据异常" + ex.ToString());
|
|
}
|
|
finally
|
|
{
|
|
lock (m_Lock)
|
|
{
|
|
b_In = false;
|
|
}
|
|
}
|
|
}
|
|
|
|
private string ConvertData(object data, string type)
|
|
{
|
|
if (data.GetType().FullName == "System.DBNull")
|
|
return "NULL";
|
|
string value;
|
|
switch (type)
|
|
{
|
|
case "VARCHAR":
|
|
{
|
|
value = data.ToString();
|
|
if (value.IndexOf("\r") > 0)
|
|
value = value.Replace("\r", "\\r");
|
|
if (value.IndexOf("\n") > 0)
|
|
value = value.Replace("\n", "\\n");
|
|
if (value.IndexOf("'") > 0)
|
|
value = value.Replace("'", "''");
|
|
if (value.IndexOf("\\") > 0)
|
|
value = value.Replace("\\", "\\\\");
|
|
value = $"'{value}'";
|
|
break;
|
|
}
|
|
case "JSON":
|
|
{
|
|
value = data.ToString().Trim() == "" ? "NULL" : $"'{data.ToString()}'";
|
|
break;
|
|
}
|
|
case "TIMESTAMP":
|
|
value = data.ToString().Trim() == "" ? "NULL" : $"'{Convert.ToDateTime(data.ToString()).ToString("yyyy-MM-dd HH:mm:ss")}'";
|
|
break;
|
|
case "DATE":
|
|
value = data.ToString().Trim() == "" ? "NULL" : $"'{Convert.ToDateTime(data.ToString()).ToString("yyyy-MM-dd")}'";
|
|
break;
|
|
default:
|
|
value = data.ToString().Trim() == "" ? "NULL" : data.ToString();
|
|
break;
|
|
}
|
|
return value;
|
|
}
|
|
|
|
private void WriteToFile(string content)
|
|
{
|
|
if (!File.Exists(m_FileName))
|
|
{
|
|
using (StreamWriter sw = File.CreateText(m_FileName))
|
|
{
|
|
sw.Write(content);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
using (StreamWriter sw = File.AppendText(m_FileName))
|
|
{
|
|
sw.Write(content);
|
|
}
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
#region 进度
|
|
private void SetTotal(int max, int value)
|
|
{
|
|
try
|
|
{
|
|
this.BeginInvoke(new EventHandler(delegate
|
|
{
|
|
progressBar_Main.Minimum = 0;
|
|
progressBar_Main.Maximum = max;
|
|
progressBar_Main.Value = value;
|
|
lbl_pro.Text = $"{value}/{max}";
|
|
}));
|
|
}
|
|
catch { }
|
|
}
|
|
#endregion
|
|
|
|
#region 加载配置项
|
|
DBExportConf m_DBExportConf;
|
|
private void LoadConf()
|
|
{
|
|
try
|
|
{
|
|
string fname = AppDomain.CurrentDomain.BaseDirectory + @"\Config\DBExportConfig.json";
|
|
if (File.Exists(fname))
|
|
m_DBExportConf = Newtonsoft.Json.JsonConvert.DeserializeObject<DBExportConf>(File.ReadAllText(fname));
|
|
}
|
|
catch { }
|
|
}
|
|
#endregion
|
|
}
|
|
|
|
#region 配置项
|
|
public class Content
|
|
{
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
public List<string> All { get; set; }
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
public List<string> Except { get; set; }
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
public List<string> Limit { get; set; }
|
|
}
|
|
|
|
public class DBExportConf
|
|
{
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
public Content Content { get; set; }
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
public int LimitTime { get; set; }
|
|
}
|
|
#endregion
|
|
}
|
|
|