diff --git a/ProcessManage.sln b/ProcessManage.sln new file mode 100644 index 0000000..d332ce2 --- /dev/null +++ b/ProcessManage.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.14.36202.13 d17.14 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ProcessManage", "ProcessManage\ProcessManage.csproj", "{C23B5C86-638A-431E-939B-591CDF8CF6D3}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {C23B5C86-638A-431E-939B-591CDF8CF6D3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C23B5C86-638A-431E-939B-591CDF8CF6D3}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C23B5C86-638A-431E-939B-591CDF8CF6D3}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C23B5C86-638A-431E-939B-591CDF8CF6D3}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {27BEF72D-8965-44C7-A72E-C25F919388E2} + EndGlobalSection +EndGlobal diff --git a/ProcessManage/App.config b/ProcessManage/App.config new file mode 100644 index 0000000..56efbc7 --- /dev/null +++ b/ProcessManage/App.config @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/ProcessManage/ClsLock.cs b/ProcessManage/ClsLock.cs new file mode 100644 index 0000000..496a207 --- /dev/null +++ b/ProcessManage/ClsLock.cs @@ -0,0 +1,138 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; + +namespace ProcessManage +{ + /// + /// 使用using代替lock操作的对象,可指定写入和读取锁定模式 + /// + public sealed class ClsLock + { + #region 内部类 + + /// + /// 利用IDisposable的using语法糖方便的释放锁定操作内部类 + /// + private struct Lock : IDisposable + { + /// + /// 读写锁对象 + /// + private readonly ReaderWriterLockSlim _Lock; + /// + /// 是否为写入模式 + /// + private bool _IsWrite; + /// + /// 利用IDisposable的using语法糖方便的释放锁定操作构造函数 + /// + /// 读写锁 + /// 写入模式为true,读取模式为false + public Lock(ReaderWriterLockSlim rwl, bool isWrite) + { + _Lock = rwl; + _IsWrite = isWrite; + } + /// + /// 释放对象时退出指定锁定模式 + /// + public void Dispose() + { + if (_IsWrite) + { + if (_Lock.IsWriteLockHeld) + { + _Lock.ExitWriteLock(); + } + } + else + { + if (_Lock.IsReadLockHeld) + { + _Lock.ExitReadLock(); + } + } + } + } + + /// + /// 空的可释放对象,免去了调用时需要判断是否为null的问题内部类 + /// + private class Disposable : IDisposable + { + /// + /// 空的可释放对象 + /// + public static readonly Disposable Empty = new Disposable(); + /// + /// 空的释放方法 + /// + public void Dispose() { } + } + + #endregion + + /// + /// 读写锁 + /// + private readonly ReaderWriterLockSlim _LockSlim = new ReaderWriterLockSlim(); + /// + /// 使用using代替lock操作的对象,可指定写入和读取锁定模式构造函数 + /// + public ClsLock() + { + Enabled = true; + } + /// + /// 是否启用,当该值为false时,Read()和Write()方法将返回 Disposable.Empty + /// + public bool Enabled { get; set; } + + /// + /// 进入读取锁定模式,该模式下允许多个读操作同时进行, + /// 退出读锁请将返回对象释放,建议使用using语块, + /// Enabled为false时,返回Disposable.Empty, + /// 在读取或写入锁定模式下重复执行,返回Disposable.Empty; + /// + public IDisposable Read() + { + if (Enabled == false || _LockSlim.IsReadLockHeld || _LockSlim.IsWriteLockHeld) + { + return Disposable.Empty; + } + else + { + _LockSlim.EnterReadLock(); + return new Lock(_LockSlim, false); + } + } + + /// + /// 进入写入锁定模式,该模式下只允许同时执行一个读操作, + /// 退出读锁请将返回对象释放,建议使用using语块, + /// Enabled为false时,返回Disposable.Empty, + /// 在写入锁定模式下重复执行,返回Disposable.Empty + /// + /// 读取模式下不能进入写入锁定状态 + public IDisposable Write() + { + if (Enabled == false || _LockSlim.IsWriteLockHeld) + { + return Disposable.Empty; + } + else if (_LockSlim.IsReadLockHeld) + { + throw new NotImplementedException("读取模式下不能进入写入锁定状态"); + } + else + { + _LockSlim.EnterWriteLock(); + return new Lock(_LockSlim, true); + } + } + } +} diff --git a/ProcessManage/IniFile.cs b/ProcessManage/IniFile.cs new file mode 100644 index 0000000..64342fc --- /dev/null +++ b/ProcessManage/IniFile.cs @@ -0,0 +1,52 @@ +using System.Runtime.InteropServices; +using System.Text; + +namespace ProcessManage +{ + internal class IniFile + { + public class IniFiles + { + public string path; + [DllImport("kernel32")] //返回0表示失败,非0为成功 + private static extern long WritePrivateProfileString(string section, string key, string val, string filePath); + [DllImport("kernel32")] //返回取得字符串缓冲区的长度 + private static extern int GetPrivateProfileString(string section, string key, string def, StringBuilder retVal, int size, string filePath); + /// + /// 保存ini文件的路径 + /// 调用示例:var ini = IniFiles("C:\file.ini"); + /// + /// + public IniFiles(string iniPath) + { + this.path = iniPath; + } + /// + /// 写Ini文件 + /// 调用示例:ini.IniWritevalue("Server","name","localhost"); + /// + /// [缓冲区] + /// 键 + /// 值 + public void IniWritevalue(string Section, string Key, string value) + { + WritePrivateProfileString(Section, Key, value, this.path); + } + /// + /// 读Ini文件 + /// 调用示例:ini.IniWritevalue("Server","name"); + /// + /// [缓冲区] + /// 键 + /// + public string IniReadvalue(string Section, string Key) + { + StringBuilder temp = new StringBuilder(255); + + int i = GetPrivateProfileString(Section, Key, "", temp, 255, this.path); + return temp.ToString(); + } + + } + } +} diff --git a/ProcessManage/LogGing.cs b/ProcessManage/LogGing.cs new file mode 100644 index 0000000..fb16b6f --- /dev/null +++ b/ProcessManage/LogGing.cs @@ -0,0 +1,118 @@ +using System; +using System.Collections.Generic; +using System.Data; +using System.IO; + +namespace ProcessManage +{ + public class LogGing + { + public static void LogGingDATA(string dat) + { + string logpath = System.Environment.CurrentDirectory + "\\Log";//日志文件目录 + string logPath = "" + System.Environment.CurrentDirectory + "\\Log\\" + DateTime.Now.ToString("yyyy-MM-dd") + ".txt";//日志文件 + string Log_time = "[" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "]:"; + + if (Directory.Exists(logpath))//检查日志路径 + { + if (!File.Exists(logPath))//检查日志文件并写入启动日志 + { + FileStream fs = new FileStream(logPath, FileMode.CreateNew, FileAccess.Write);//创建写入文件 + StreamWriter wr = new StreamWriter(fs);//创建文件 + wr.WriteLine(Log_time + dat); + wr.Close(); + } + else + { + try + { + FileStream fs = new FileStream(logPath, FileMode.Append, FileAccess.Write); + StreamWriter wr = new StreamWriter(fs);//创建文件 + wr.WriteLine(Log_time + dat); + wr.Close(); + } + catch { } + } + } + else + { + DirectoryInfo directoryInfo = new DirectoryInfo(logpath); + directoryInfo.Create();//创建日志路径 + } + } + public static void ERRDATA(System.Exception dat) + { + string Log_time = DateTime.Now.ToString("yyyy-MM-dd"); + string logpath = System.Environment.CurrentDirectory + "\\ERR";//日志文件目录 + // string logPathtxt = "" + System.Environment.CurrentDirectory + "\\Log\\"+ Log_time + "Log.txt";//日志文件 + // System.IO.DirectoryInfo log = new System.IO.DirectoryInfo();//生成日志文件目录 + string log_path = logpath + "\\ERR" + Log_time + ".txt"; + string Log_timehms = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); + if (Directory.Exists(logpath))//检查日志路径 + { + if (!File.Exists(log_path))//检查文件并写入 + { + // FileStream fs = new FileStream(log_path, FileMode.CreateNew, FileAccess.Write);//创建文件 + // StreamWriter wr = new StreamWriter(fs);//创建文件 + // wr.Close(); + FileStream fil = new FileStream(log_path, FileMode.CreateNew, FileAccess.Write);//创建写入文件 + StreamWriter wfil = new StreamWriter(fil);//创建文件 + wfil.WriteLine("[" + Log_timehms + "];[Error] ||" + Environment.NewLine.ToString()); + wfil.WriteLine("[" + Log_timehms + "];[Error source] ||" + dat.Source.ToString() + Environment.NewLine.ToString()); + wfil.WriteLine("[" + Log_timehms + "];[Error message] ||" + dat.Message.ToString() + Environment.NewLine.ToString()); + wfil.WriteLine("[" + Log_timehms + "];[Error area] ||" + dat.StackTrace.ToString()); + wfil.Close(); + } + else + { + FileStream fs = new FileStream(log_path, FileMode.Append, FileAccess.Write);//创建写入文件 + StreamWriter wr = new StreamWriter(fs);//创建文件 + wr.WriteLine("[" + Log_timehms + "];[Error] ||" + Environment.NewLine.ToString()); + wr.WriteLine("[" + Log_timehms + "];[Error source] ||" + dat.ToString() + Environment.NewLine.ToString()); + wr.WriteLine("[" + Log_timehms + "];[Error message] ||" + dat.Message.ToString() + Environment.NewLine.ToString()); + wr.WriteLine("[" + Log_timehms + "];[Error area] ||" + dat.ToString()); + wr.Close(); + } + } + else + { + DirectoryInfo directoryInfo = new DirectoryInfo(logpath); + directoryInfo.Create(); + } + } + public static void ExchangeDATA(string dat) + { + string Log_time = DateTime.Now.ToString("yyyy-MM-dd"); + string logpath = System.Environment.CurrentDirectory + "\\Exchange";//日志文件目录 + // string logPathtxt = "" + System.Environment.CurrentDirectory + "\\Log\\"+ Log_time + "Log.txt";//日志文件 + // System.IO.DirectoryInfo log = new System.IO.DirectoryInfo();//生成日志文件目录 + string log_path = logpath + "\\Exchange" + Log_time + ".txt"; + string Log_timehms = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); + if (Directory.Exists(logpath))//检查日志路径 + { + if (!File.Exists(log_path))//检查文件并写入 + { + // FileStream fs = new FileStream(log_path, FileMode.CreateNew, FileAccess.Write);//创建文件 + // StreamWriter wr = new StreamWriter(fs);//创建文件 + // wr.Close(); + FileStream fil = new FileStream(log_path, FileMode.CreateNew, FileAccess.Write);//创建写入文件 + StreamWriter wfil = new StreamWriter(fil);//创建文件 + wfil.WriteLine("[" + Log_timehms + "];[Exchange] ||" + dat); + wfil.Close(); + } + else + { + FileStream fs = new FileStream(log_path, FileMode.Append, FileAccess.Write);//创建写入文件 + StreamWriter wr = new StreamWriter(fs);//创建文件 + wr.WriteLine("[" + Log_timehms + "];[Exchange] ||" + dat); + wr.Close(); + } + } + else + { + DirectoryInfo directoryInfo = new DirectoryInfo(logpath); + directoryInfo.Create(); + } + } + } +} diff --git a/ProcessManage/ProcessManage.csproj b/ProcessManage/ProcessManage.csproj new file mode 100644 index 0000000..2fe0cf4 --- /dev/null +++ b/ProcessManage/ProcessManage.csproj @@ -0,0 +1,62 @@ + + + + + Debug + AnyCPU + {C23B5C86-638A-431E-939B-591CDF8CF6D3} + Exe + ProcessManage + ProcessManage + v4.7.2 + 512 + true + true + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + + + + + + + + + + + + + 1.0.119 + + + + \ No newline at end of file diff --git a/ProcessManage/Program.cs b/ProcessManage/Program.cs new file mode 100644 index 0000000..a9cc255 --- /dev/null +++ b/ProcessManage/Program.cs @@ -0,0 +1,83 @@ +using System; +using System.Collections.Generic; +using System.Data; +using System.Data.SqlClient; +using System.Linq; +using System.Security.Cryptography; +using System.Text; +using System.Threading; +using System.Threading.Tasks; + +namespace ProcessManage +{ + internal class Program + { + private static IniFile.IniFiles Configini = new IniFile.IniFiles(Convert.ToString(System.AppDomain.CurrentDomain.BaseDirectory) + "ProcessManageConfigini.ini"); + private static string SQLIP = Configini.IniReadvalue("SQL_SERVER", "SQL1"); //读配置文件 + private static string SQLNAME = Configini.IniReadvalue("SQL_SERVER", "SQL2"); + private static string SQMOD = Configini.IniReadvalue("SQL_SERVER", "SQL3"); + private static string SQLUSER = Configini.IniReadvalue("SQL_SERVER", "SQL4"); + private static string SQLPASWORD = Configini.IniReadvalue("SQL_SERVER", "SQL5"); + private static DataTable DyelotsBulkedRecipe = new DataTable(); + private static Timer _timer; + private static int Count = 0; + private static readonly int _intervalMs = int.Parse( Configini.IniReadvalue("SQL_SERVER", "SQL6")); + static void Main(string[] args) + { + Console.WriteLine("Process选择功能启动"); + _timer = new Timer( + callback: EXTask, + state: null, + dueTime: 100, + period: Timeout.Infinite); + + Console.ReadKey();//等待退出 + + _timer?.Dispose();//清理 + Console.WriteLine("程序退出"); + } + + private static void EXTask(object state) + { + string Connstr_SC; + string DyelotsBulkedRecipe_sql = "SELECT * FROM [dbo].[DyelotsBulkedRecipe] WHERE Created > '" + + DateTime.Now.AddDays(-1).ToString("yyyy/MM/dd") + "' AND Process IS NULL"; + try + { + DyelotsBulkedRecipe.Clear(); + + if (SQMOD == "Windows Authentication") + { + Connstr_SC = "server=" + SQLIP + ";database=" + SQLNAME + ";Trusted_Connection=SSPI"; + } + else + { + Connstr_SC = "server=" + SQLIP + ";database=" + SQLNAME + ";User ID=" + SQLUSER + ";Password=" + SQLPASWORD; + } + SqlConnection conn_SC = new SqlConnection(Connstr_SC); + conn_SC.OpenAsync(); //连接数据库 + SqlDataAdapter DyelotsBulkedRecipe_ = new SqlDataAdapter(DyelotsBulkedRecipe_sql, Connstr_SC); + conn_SC.Close(); + DyelotsBulkedRecipe_.Fill(DyelotsBulkedRecipe); + + + + + + Console.Write("\n"+DateTime.Now.ToString("yyyy/MM/dd-HH:mm:ss")+$"转换{Count}条"); + Count = 0; + } + catch (Exception ex) + {//错误处理 + LogGing.ERRDATA(ex); + Console.Write(ex.ToString()); + } + finally + { + _timer.Change( + dueTime: _intervalMs, + period: Timeout.Infinite);//设定下次触发 + } + } + } +} diff --git a/ProcessManage/Properties/AssemblyInfo.cs b/ProcessManage/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..7acd41d --- /dev/null +++ b/ProcessManage/Properties/AssemblyInfo.cs @@ -0,0 +1,33 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// 有关程序集的一般信息由以下 +// 控制。更改这些特性值可修改 +// 与程序集关联的信息。 +[assembly: AssemblyTitle("ProcessManage")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("ProcessManage")] +[assembly: AssemblyCopyright("Copyright © 2025")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// 将 ComVisible 设置为 false 会使此程序集中的类型 +//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型 +//请将此类型的 ComVisible 特性设置为 true。 +[assembly: ComVisible(false)] + +// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID +[assembly: Guid("c23b5c86-638a-431e-939b-591cdf8cf6d3")] + +// 程序集的版本信息由下列四个值组成: +// +// 主版本 +// 次版本 +// 生成号 +// 修订号 +// +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/ProcessManage/SqliteHelper.cs b/ProcessManage/SqliteHelper.cs new file mode 100644 index 0000000..944d01a --- /dev/null +++ b/ProcessManage/SqliteHelper.cs @@ -0,0 +1,684 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Data; +using System.IO; +using System.Data.Common; +using System.Data.SQLite; +using System.Drawing; + + +namespace ProcessManage +{ + public class SqliteHelper + { + + public class SQLiteHelper + { + #region 字段 + + /// + /// 事务的基类 + /// + private DbTransaction DBtrans; + /// + /// 使用静态变量字典解决多线程实例本类,实现一个数据库对应一个clslock + /// + private static readonly Dictionary RWL = new Dictionary(); + /// + /// 数据库地址 + /// + private readonly string mdataFile; + /// + /// 数据库密码 + /// + private readonly string mPassWord; + private readonly string LockName = null; + /// + /// 数据库连接定义 + /// + private SQLiteConnection mConn; + + #endregion + + #region 构造函数 + + /// + /// 根据数据库地址初始化 + /// + /// 数据库地址 + public SQLiteHelper(string dataFile) + { + this.mdataFile = dataFile ?? throw new ArgumentNullException("dataFile=null"); + //this.mdataFile = AppDomain.CurrentDomain.BaseDirectory + dataFile; + this.mdataFile = dataFile; + if (!RWL.ContainsKey(dataFile)) + { + LockName = dataFile; + RWL.Add(dataFile, new ClsLock()); + } + } + + /// + /// 使用密码打开数据库 + /// + /// 数据库地址 + /// 数据库密码 + public SQLiteHelper(string dataFile, string PassWord) + { + this.mdataFile = dataFile ?? throw new ArgumentNullException("dataFile is null"); + this.mPassWord = PassWord ?? throw new ArgumentNullException("PassWord is null"); + //this.mdataFile = AppDomain.CurrentDomain.BaseDirectory + dataFile; + this.mdataFile = dataFile; + if (!RWL.ContainsKey(dataFile)) + { + LockName = dataFile; + RWL.Add(dataFile, new ClsLock()); + } + } + + #endregion + + #region 打开/关闭 数据库 + + /// + /// 打开 SQLiteManager 使用的数据库连接 + /// + public void Open() + { + if (string.IsNullOrWhiteSpace(mPassWord)) + { + mConn = OpenConnection(this.mdataFile); + } + else + { + mConn = OpenConnection(this.mdataFile, mPassWord); + } + Console.WriteLine("The database was opened successfully"); + } + + /// + /// 关闭连接 + /// + public void Close() + { + if (this.mConn != null) + { + try + { + this.mConn.Close(); + if (RWL.ContainsKey(LockName)) + { + RWL.Remove(LockName); + } + } + catch + { + Console.WriteLine("Shutdown failed"); + } + } + Console.WriteLine("The database was shut down successfully"); + } + + #endregion + + #region 事务 + + /// + /// 开始事务 + /// + public void BeginTrain() + { + EnsureConnection(); + DBtrans = mConn.BeginTransaction(); + } + + /// + /// 提交事务 + /// + public void DBCommit() + { + try + { + DBtrans.Commit(); + } + catch (Exception) + { + DBtrans.Rollback(); + } + } + + #endregion + + #region 工具 + + /// + /// 打开一个SQLite数据库文件,如果文件不存在,则创建(无密码) + /// + /// + /// SQLiteConnection 类 + private SQLiteConnection OpenConnection(string dataFile) + { + if (dataFile == null) + { + throw new ArgumentNullException("dataFiledataFile=null"); + } + if (!File.Exists(dataFile)) + { + SQLiteConnection.CreateFile(dataFile); + } + SQLiteConnection conn = new SQLiteConnection(); + SQLiteConnectionStringBuilder conStr = new SQLiteConnectionStringBuilder + { + DataSource = dataFile + }; + conn.ConnectionString = conStr.ToString(); + conn.Open(); + return conn; + } + + /// + /// 打开一个SQLite数据库文件,如果文件不存在,则创建(有密码) + /// + /// + /// + /// SQLiteConnection 类 + private SQLiteConnection OpenConnection(string dataFile, string Password) + { + if (dataFile == null) + { + throw new ArgumentNullException("dataFile=null"); + } + if (!File.Exists(Convert.ToString(dataFile))) + { + SQLiteConnection.CreateFile(dataFile); + } + try + { + SQLiteConnection conn = new SQLiteConnection(); + SQLiteConnectionStringBuilder conStr = new SQLiteConnectionStringBuilder + { + DataSource = dataFile, + Password = Password + }; + conn.ConnectionString = conStr.ToString(); + conn.Open(); + return conn; + } + catch (Exception) + { + return null; + } + } + + /// + /// 读取 或 设置 SQLiteManager 使用的数据库连接 + /// + public SQLiteConnection Connection + { + get + { + return mConn; + } + private set + { + mConn = value ?? throw new ArgumentNullException(); + } + } + + /// + /// 确保数据库是连接状态 + /// + /// + protected void EnsureConnection() + { + if (this.mConn == null) + { + throw new Exception("SQLiteManager.Connection=null"); + } + if (mConn.State != ConnectionState.Open) + { + mConn.Open(); + } + } + + /// + /// 获取数据库文件的路径 + /// + /// + public string GetDataFile() + { + return this.mdataFile; + } + + /// + /// 判断表 table 是否存在 + /// + /// + /// 存在返回true,否则返回false + public bool TableExists(string table) + { + if (table == null) + { + throw new ArgumentNullException("table=null"); + } + EnsureConnection(); + SQLiteDataReader reader = ExecuteReader("SELECT count(*) as c FROM sqlite_master WHERE type='table' AND name=@tableName ", new SQLiteParameter[] { new SQLiteParameter("tableName", table) }); + if (reader == null) + { + return false; + } + reader.Read(); + int c = reader.GetInt32(0); + reader.Close(); + reader.Dispose(); + //return false; + return c == 1; + } + + /// + /// VACUUM 命令(通过复制主数据库中的内容到一个临时数据库文件,然后清空主数据库,并从副本中重新载入原始的数据库文件) + /// + /// + public bool Vacuum() + { + try + { + using (SQLiteCommand Command = new SQLiteCommand("VACUUM", Connection)) + { + Command.ExecuteNonQuery(); + } + return true; + } + catch (System.Data.SQLite.SQLiteException) + { + return false; + } + } + + #endregion + + #region 执行SQL + + /// + /// 执行SQL, 并返回 SQLiteDataReader 对象结果 + /// + /// + /// null 表示无参数 + /// + public SQLiteDataReader ExecuteReader(string sql, SQLiteParameter[] paramArr) + { + if (sql == null) + { + throw new ArgumentNullException("sql=null"); + } + EnsureConnection(); + using (RWL[LockName].Read()) + { + using (SQLiteCommand cmd = new SQLiteCommand(sql, Connection)) + { + if (paramArr != null) + { + cmd.Parameters.AddRange(paramArr); + } + try + { + SQLiteDataReader reader = cmd.ExecuteReader(); + cmd.Parameters.Clear(); + return reader; + } + catch (Exception) + { + return null; + } + } + } + } + + /// + /// 执行查询,并返回dataset对象 + /// + /// SQL查询语句 + /// 参数数组 + /// + public DataSet ExecuteDataSet(string sql, SQLiteParameter[] paramArr) + { + if (sql == null) + { + throw new ArgumentNullException("sql=null"); + } + this.EnsureConnection(); + using (RWL[LockName].Read()) + { + using (SQLiteCommand cmd = new SQLiteCommand(sql, this.Connection)) + { + if (paramArr != null) + { + cmd.Parameters.AddRange(paramArr); + } + try + { + SQLiteDataAdapter da = new SQLiteDataAdapter(); + DataSet ds = new DataSet(); + da.SelectCommand = cmd; + da.Fill(ds); + cmd.Parameters.Clear(); + da.Dispose(); + return ds; + } + catch (Exception) + { + return null; + } + } + } + } + + /// + /// 执行SQL查询,并返回dataset对象。 + /// + /// 映射源表的名称 + /// SQL语句 + /// SQL参数数组 + /// + public DataSet ExecuteDataSet(string strTable, string sql, SQLiteParameter[] paramArr) + { + if (sql == null) + { + throw new ArgumentNullException("sql=null"); + } + this.EnsureConnection(); + using (RWL[LockName].Read()) + { + using (SQLiteCommand cmd = new SQLiteCommand(sql, this.Connection)) + { + if (paramArr != null) + { + cmd.Parameters.AddRange(paramArr); + } + try + { + SQLiteDataAdapter da = new SQLiteDataAdapter(); + DataSet ds = new DataSet(); + da.SelectCommand = cmd; + da.Fill(ds, strTable); + cmd.Parameters.Clear(); + da.Dispose(); + return ds; + } + catch (Exception) + { + return null; + } + } + } + } + + /// + /// 执行SQL,返回受影响的行数,可用于执行表创建语句,paramArr == null 表示无参数 + /// + /// + /// + public int ExecuteNonQuery(string sql, SQLiteParameter[] paramArr) + { + if (sql == null) + { + throw new ArgumentNullException("sql=null"); + } + this.EnsureConnection(); + using (RWL[LockName].Read()) + { + try + { + using (SQLiteCommand cmd = new SQLiteCommand(sql, Connection)) + { + if (paramArr != null) + { + foreach (SQLiteParameter p in paramArr) + { + cmd.Parameters.Add(p); + } + } + int c = cmd.ExecuteNonQuery(); + cmd.Parameters.Clear(); + return c; + } + } + catch (SQLiteException) + { + return 0; + } + } + } + + /// + /// 执行SQL,返回结果集第一行,如果结果集为空,那么返回空 List(List.Count=0), + /// rowWrapper = null 时,使用 WrapRowToDictionary + /// + /// + /// + /// + public object ExecuteScalar(string sql, SQLiteParameter[] paramArr) + { + if (sql == null) + { + throw new ArgumentNullException("sql=null"); + } + this.EnsureConnection(); + using (RWL[LockName].Read()) + { + using (SQLiteCommand cmd = new SQLiteCommand(sql, Connection)) + { + if (paramArr != null) + { + cmd.Parameters.AddRange(paramArr); + } + try + { + object reader = cmd.ExecuteScalar(); + cmd.Parameters.Clear(); + cmd.Dispose(); + return reader; + } + catch (Exception) + { + return null; + } + } + } + } + + /// + /// 查询一行记录,无结果时返回 null,conditionCol = null 时将忽略条件,直接执行 select * from table + /// + /// 表名 + /// + /// + /// + public object QueryOne(string table, string conditionCol, object conditionVal) + { + if (table == null) + { + throw new ArgumentNullException("table=null"); + } + this.EnsureConnection(); + string sql = "select * from " + table; + if (conditionCol != null) + { + sql += " where " + conditionCol + "=@" + conditionCol; + } + object result = ExecuteScalar(sql, new SQLiteParameter[] { new SQLiteParameter(conditionCol, conditionVal) }); + return result; + } + + #endregion + + #region 增 删 改 + + /// + /// 执行 insert into 语句 + /// + /// + /// + /// + public int InsertData(string table, Dictionary entity) + { + if (table == null) + { + throw new ArgumentNullException("table=null"); + } + this.EnsureConnection(); + string sql = BuildInsert(table, entity); + return this.ExecuteNonQuery(sql, BuildParamArray(entity)); + } + + /// + /// 执行 update 语句,注意:如果 where = null,那么 whereParams 也为 null, + /// + /// 表名 + /// 要修改的列名和列名的值 + /// 查找符合条件的列 + /// where条件中参数的值 + /// + public int Update(string table, Dictionary entity, string where, SQLiteParameter[] whereParams) + { + if (table == null) + { + throw new ArgumentNullException("table=null"); + } + this.EnsureConnection(); + string sql = BuildUpdate(table, entity); + SQLiteParameter[] parameter = BuildParamArray(entity); + if (where != null) + { + sql += " where " + where; + if (whereParams != null) + { + SQLiteParameter[] newArr = new SQLiteParameter[(parameter.Length + whereParams.Length)]; + Array.Copy(parameter, newArr, parameter.Length); + Array.Copy(whereParams, 0, newArr, parameter.Length, whereParams.Length); + parameter = newArr; + } + } + return this.ExecuteNonQuery(sql, parameter); + } + + /// + /// 执行 delete from table 语句,where不必包含'where'关键字,where = null 时将忽略 whereParams + /// + /// + /// + /// + /// + public int Delete(string table, string where, SQLiteParameter[] whereParams) + { + if (table == null) + { + throw new ArgumentNullException("table=null"); + } + this.EnsureConnection(); + string sql = "delete from " + table + " "; + if (where != null) + { + sql += "where " + where; + } + return ExecuteNonQuery(sql, whereParams); + } + + /// + /// 将 Dictionary 类型数据 转换为 SQLiteParameter[] 类型 + /// + /// + /// + private SQLiteParameter[] BuildParamArray(Dictionary entity) + { + List list = new List(); + foreach (string key in entity.Keys) + { + list.Add(new SQLiteParameter(key, entity[key])); + } + if (list.Count == 0) + { + return null; + } + return list.ToArray(); + } + + /// + /// 将 Dictionary 类型数据 转换为 插入数据 的 SQL语句 + /// + /// 表名 + /// 字典 + /// + private string BuildInsert(string table, Dictionary entity) + { + StringBuilder buf = new StringBuilder(); + buf.Append("insert into ").Append(table); + buf.Append(" ("); + foreach (string key in entity.Keys) + { + buf.Append(key).Append(","); + } + buf.Remove(buf.Length - 1, 1); // 移除最后一个, + buf.Append(") "); + buf.Append("values("); + foreach (string key in entity.Keys) + { + buf.Append("@").Append(key).Append(","); // 创建一个参数 + } + buf.Remove(buf.Length - 1, 1); + buf.Append(") "); + + return buf.ToString(); + } + + /// + /// 将 Dictionary 类型数据 转换为 修改数据 的 SQL语句 + /// + /// 表名 + /// 字典 + /// + private string BuildUpdate(string table, Dictionary entity) + { + StringBuilder buf = new StringBuilder(); + buf.Append("update ").Append(table).Append(" set "); + foreach (string key in entity.Keys) + { + buf.Append(key).Append("=").Append("@").Append(key).Append(","); + } + buf.Remove(buf.Length - 1, 1); + buf.Append(" "); + return buf.ToString(); + } + + /// + /// 将 DataTable 转换为 Dictionary 类型数据 + /// + public Dictionary DataTableToDictionary(DataTable dataTable) + { + Dictionary result = new Dictionary(); + if (dataTable != null) + { + foreach (DataRow dataRow in dataTable.Rows) + { + foreach (DataColumn dataColumn in dataTable.Columns) + { + result.Add(dataColumn.ColumnName, dataRow[dataColumn].ToString()); + //result = Console.WriteLine(dataRow[dataColumn].ToString()); + //result.Add(dataColumn.ColumnName, dataRow[dataColumn].ToString())(new RepeatDictionaryComparer()); + } + } + } + else + { + result = null; + } + return result; + } + + } + #endregion + } +}