由于项目需要,我写了一个初始MySQL数据库的工具;
一, 思路:
(1),首先读取包含mysql语句的脚本(其中有创建数据库,表,插入初始数据等!)。
(2),然后替换里面的一些数据值(如guid,注释等!)。
(3),把替换后的数据流重新写入mysql脚本。
(4),调用MySQL命令执行相应的命令。
主要思路结束!
二, 现具体过程如下:
1,主界面如图:
2,全局代码和构造方法如下:
string IP;
string userName;
string userPwd;
string path;
string mesg = "";
Boolean info = false;
//字符串形式的guid
string _guID = "";
string timeMesg = "";
int i = 0;
//测量间隔运行时间
Stopwatch stop = new Stopwatch();
public ToolForm()
{
InitializeComponent();
}
3,在按钮事件中验证了各个文本框中的值是否为空;IP地址和端口号的验证!
代码如下:
/**//// <summary>
/// 按钮事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnOK_Click(object sender, EventArgs e)
{
i = 0;
this.lbMessage.Text = "";
IP = this.tbIP.Text.Trim();
userName = this.tbUserName.Text.Trim();
userPwd = this.tbPWD.Text.Trim();
DirPath = Application.StartupPath;
Regex regexIP = new Regex(@"^((0|1[0-9]{0,2}|2[0-9]{0,1}|2[0-4][0-9]|25[0-5]|[3-9][0-9]{0,1})\.){3}(0|1[0-9]{0,2}|2[0-9]{0,1}|2[0-4][0-9]|25[0-5]|[3-9][0-9]{0,1})$");
if ( string.IsNullOrEmpty(IP))
{
MessageBox.Show("请输入服务器地址!");
this.tbIP.Focus();
return;
}
else if (string.IsNullOrEmpty(userName))
{
MessageBox.Show("请输入用户名!");
this.tbUserName.Focus();
return;
}
else if (string.IsNullOrEmpty(userPwd))
{
MessageBox.Show("请输入密码!");
this.tbPWD.Focus();
return;
}
else if (regexIP.IsMatch(IP) || (string.Compare(IP,"localhost",true)== 0))
{
//得到目录下的所有文件
string[] files = Directory.GetFiles(DirPath);
//循环读文件
foreach (string file in files)
{
//如果后缀名为.sql文件
if (".sql".IndexOf(file.Substring(file.LastIndexOf(".") + 1)) > -1)
{
//把.sql文件全名加人到fileList集合中
fileList.Add(file);
}
}
if (fileList.Count > 1)
{
MessageBox.Show("目录下多个.sql文件!该程序只能读一个!");
return;
}
else if (fileList.Count < 1)
{
MessageBox.Show("目录下没有.sql文件!");
return;
}
else
{
path = fileList.First();
this.lbMessage.Text = "正在导入数据!请稍等..";
//测量时间开始
stop.Start();
//调用主方法
MainMethod();
}
}
else
{
MessageBox.Show("服务器IP地址不规范!");
this.tbIP.Focus();
return;
}
}
4, 如果输入符和规范,则调用主方法(主方法里实现思路中主要方法的调用);
主方法代码如下:
/**//// <summary>
/// 主方法
/// </summary>
/// <param name="IP"></param>
/// <param name="userName"></param>
/// <param name="userPwd"></param>
/// <param name="path"></param>
/// <returns></returns>
private void MainMethod()
{
try
{
//读文件
string fileRed = ReadSQLFromFile(path);
//写文件
File.WriteAllText(path, fileRed);
//调用进度条的timer
this.timer1.Start();
//调用执行脚本文件的timer
this.timer2.Start();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
5, 读脚本文件,替换guid标识的方法;
代码如下:
/**//// <summary>
/// 读文件流,替换guid标示
/// </summary>
/// <param name="strQuery"></param>
/// <param name="path"></param>
/// <returns></returns>
private string ReadSQLFromFile( string path)
{
//新生成一个guid
Guid guId = Guid.NewGuid();
//把guid转换为字符串形式的guid
_guID = "{" + guId + "}";
FileStream fs = null;
string strQuery = "";
try
{
fs = new FileStream(path, FileMode.Open, FileAccess.Read);
string strTemp = Encoding.UTF8.GetString(ConvertStreamToByteBuffer(fs));
//用新生成的guid替换掉脚本文件中的guid;
strQuery = Regex.Replace(strTemp, @"(\{[A-Fa-f0-9]{8}(-[A-Fa-f0-9]{4}){3}-[A-Fa-f0-9]{12}\})+", _guID, RegexOptions.Singleline);
int indexValue = strQuery.IndexOf("USE")+3;
int indexStart = indexValue;
int indexEnd = 0;
while(strQuery.Substring(indexValue,1)!=";")
{
indexValue++;
indexEnd = indexValue;
}
DBName = strQuery.Substring(indexStart, (indexEnd - indexStart));
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
strQuery = "";
}
finally
{
fs.Close();
}
return strQuery;
}
6,把替换后的字符串写入脚本文件:
代码如下:
File.WriteAllText(path, fileRed);
7,然后是开启两个timer,一个控制进度条,另一个获取执行时间的间隔。这里略。。。
8,在获取执行时间的timer事件中,调用执行脚本文件的方法。
该方法的代码如下:
/**//// <summary>
/// 调用mysql命令来执行脚本文文件
/// </summary>
/// <param name="IP"></param>
/// <param name="userName"></param>
/// <param name="userPwd"></param>
/// <param name="path"></param>
/// <returns></returns>
public string RunCmd()
{
Stopwatch a = new Stopwatch();
long m = a.ElapsedMilliseconds;
string mesg = "";
string mesgError = "";
Process p = null;
try
{
进入cmd调用mysql命令来执行脚本文件#region 进入cmd调用mysql命令来执行脚本文件
p = new Process();
p.StartInfo.FileName = "cmd.exe";
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardInput = true;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.RedirectStandardError = true;
p.StartInfo.CreateNoWindow = true;
p.Start();
// p.StandardInput.WriteLine(@"net start mysql");
p.StandardInput.WriteLine(@"c:");
p.StandardInput.WriteLine(@"cd C:\Program Files\MySQL\MySQL Server 5.0\bin");
p.StandardInput.WriteLine(string.Format("mysql.exe -h{0} -u{1} -p{2} -f<\"{3}\"", IP, userName, userPwd, path));
p.StandardInput.WriteLine("exit");
mesgError = p.StandardError.ReadToEnd();
mesg = mesgError;
p.WaitForExit();
#endregion
}
catch (Exception err)
{
//MessageBox.Show(err.Message); //显示错误信息。
mesg = err.Message;
}
finally
{
p.Close();
}
return mesg;
}
9,把给定的文件流转换为二进制字节数组的方法,
代码如下:
把给定的文件流转换为二进制字节数组byte[] ConvertStreamToByteBuffer(System.IO.Stream theStream)#region 把给定的文件流转换为二进制字节数组byte[] ConvertStreamToByteBuffer(System.IO.Stream theStream)
/**//// <summary>
/// 把给定的文件流转换为二进制字节数组。
/// </summary>
/// <param name="theStream"></param>
/// <returns></returns>
public byte[] ConvertStreamToByteBuffer(System.IO.Stream theStream)
{
int b1;
System.IO.MemoryStream tempStream = new System.IO.MemoryStream();
while ((b1 = theStream.ReadByte()) != -1)
{
tempStream.WriteByte(((byte)b1));
}
return tempStream.ToArray();
}
#endregion
10,控制进度条的timer事件;
代码如下:
/// <summary>
/// 控制进度条显示
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void timer1_Tick(object sender, EventArgs e)
{
try
{
this.progressBar1.Value = i;
i += 10;
if (i == 1000)
{
this.timer1.Stop();
if (string.IsNullOrEmpty(mesg) && info)
{
lbMessage.Text = "数据导入成功!" + timeMesg;
new MCFrom(_guID, IP, userName, userPwd, DBName).ShowDialog();
}
else
{
lbMessage.Text = "数据导入失败!";
}
stop.Reset();
}
}
catch (System.Exception )
{
}
}
11,获取执行时间间隔的time事件;
代码如下:
/**//// <summary>
/// 调用执行脚本文件的方法,并得到从点击按钮到成功导入数据库后的间隔时间。
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void timer2_Tick(object sender, EventArgs e)
{
//执行文件中的命令
mesg = RunCmd();
this.timer2.Stop();
info = true;
timeMesg =stop.Elapsed.Seconds.ToString()+"秒";
stop.Stop();
}
12,整个小工具大体的程序代码完成!有些细节省略掉了 !请在我的随笔里查看!