using System; using System.Collections.Generic; using System.Text; using System.Data; using System.Globalization; using System.Data.SQLite; namespace IOTContainer.SQLite { public class SQLiteActuator : IDisposable { #region 构造函数 internal SQLiteActuator(SQLiteCommand command) { this._command = command; } #endregion #region 字段属性 /// /// 连接符 /// private SQLiteCommand _command; #endregion #region 数据库基本信息 public DataTable GetTableStatus() { return Select("SELECT * FROM sqlite_master;"); } public DataTable GetTableList() { DataTable dt = GetTableStatus(); DataTable dt2 = new DataTable(); dt2.Columns.Add("Tables"); for (int i = 0; i < dt.Rows.Count; i++) { string t = dt.Rows[i]["name"] + ""; if (t != "sqlite_sequence") dt2.Rows.Add(t); } return dt2; } public DataTable GetColumnStatus(string tableName) { return Select(string.Format("PRAGMA table_info(`{0}`);", tableName)); } public DataTable ShowDatabase() { return Select("PRAGMA database_list;"); } #endregion #region 查询 public void BeginTransaction() { this._command.CommandText = "begin transaction;"; this._command.ExecuteNonQuery(); } public void Commit() { this._command.CommandText = "commit;"; this._command.ExecuteNonQuery(); } public void Rollback() { this._command.CommandText = "rollback"; this._command.ExecuteNonQuery(); } public DataTable Select(string sql) { return Select(sql, new List()); } public DataTable Select(string sql, Dictionary dicParameters = null) { List lst = GetParametersList(dicParameters); return Select(sql, lst); } private DataTable Select(string sql, IEnumerable parameters = null) { this._command.CommandText = sql; if (parameters != null) { foreach (var param in parameters) { this._command.Parameters.Add(param); } } SQLiteDataAdapter da = new SQLiteDataAdapter(this._command); DataTable dt = new DataTable(); da.Fill(dt); return dt; } public void Execute(string sql) { Execute(sql, new List()); } public void Execute(string sql, Dictionary dicParameters = null) { List lst = GetParametersList(dicParameters); Execute(sql, lst); } private void Execute(string sql, IEnumerable parameters = null) { this._command.CommandText = sql; if (parameters != null) { foreach (var param in parameters) { this._command.Parameters.Add(param); } } this._command.ExecuteNonQuery(); } public object ExecuteScalar(string sql) { this._command.CommandText = sql; return this._command.ExecuteScalar(); } public object ExecuteScalar(string sql, Dictionary dicParameters = null) { List lst = GetParametersList(dicParameters); return ExecuteScalar(sql, lst); } private object ExecuteScalar(string sql, IEnumerable parameters = null) { this._command.CommandText = sql; if (parameters != null) { foreach (var parameter in parameters) { this._command.Parameters.Add(parameter); } } return this._command.ExecuteScalar(); } public dataType ExecuteScalar(string sql, Dictionary dicParameters = null) { List lst = null; if (dicParameters != null) { lst = new List(); foreach (KeyValuePair kv in dicParameters) { lst.Add(new SQLiteParameter(kv.Key, kv.Value)); } } return ExecuteScalar(sql, lst); } private dataType ExecuteScalar(string sql, IEnumerable parameters = null) { this._command.CommandText = sql; if (parameters != null) { foreach (var parameter in parameters) { this._command.Parameters.Add(parameter); } } return (dataType)Convert.ChangeType(this._command.ExecuteScalar(), typeof(dataType)); } public dataType ExecuteScalar(string sql) { this._command.CommandText = sql; return (dataType)Convert.ChangeType(this._command.ExecuteScalar(), typeof(dataType)); } private List GetParametersList(Dictionary dicParameters) { List lst = new List(); if (dicParameters != null) { foreach (KeyValuePair kv in dicParameters) { lst.Add(new SQLiteParameter(kv.Key, kv.Value)); } } return lst; } public string Escape(string data) { data = data.Replace("'", "''"); data = data.Replace("\\", "\\\\"); return data; } public void Insert(string tableName, Dictionary dic) { StringBuilder sbCol = new System.Text.StringBuilder(); StringBuilder sbVal = new System.Text.StringBuilder(); foreach (KeyValuePair kv in dic) { if (sbCol.Length == 0) { sbCol.Append("insert into "); sbCol.Append(tableName); sbCol.Append("("); } else { sbCol.Append(","); } sbCol.Append("`"); sbCol.Append(kv.Key); sbCol.Append("`"); if (sbVal.Length == 0) { sbVal.Append(" values("); } else { sbVal.Append(", "); } sbVal.Append("@v"); sbVal.Append(kv.Key); } sbCol.Append(") "); sbVal.Append(");"); this._command.CommandText = sbCol.ToString() + sbVal.ToString(); foreach (KeyValuePair kv in dic) { this._command.Parameters.AddWithValue("@v" + kv.Key, kv.Value); } this._command.ExecuteNonQuery(); } public void Update(string tableName, Dictionary dicData, string colCond, object varCond) { Dictionary dic = new Dictionary(); dic[colCond] = varCond; Update(tableName, dicData, dic); } public void Update(string tableName, Dictionary dicData, Dictionary dicCond) { if (dicData.Count == 0) throw new Exception("dicData is empty."); StringBuilder sbData = new System.Text.StringBuilder(); Dictionary _dicTypeSource = new Dictionary(); foreach (KeyValuePair kv1 in dicData) { _dicTypeSource[kv1.Key] = null; } foreach (KeyValuePair kv2 in dicCond) { if (!_dicTypeSource.ContainsKey(kv2.Key)) _dicTypeSource[kv2.Key] = null; } sbData.Append("update `"); sbData.Append(tableName); sbData.Append("` set "); bool firstRecord = true; foreach (KeyValuePair kv in dicData) { if (firstRecord) firstRecord = false; else sbData.Append(","); sbData.Append("`"); sbData.Append(kv.Key); sbData.Append("` = "); sbData.Append("@v"); sbData.Append(kv.Key); } sbData.Append(" where "); firstRecord = true; foreach (KeyValuePair kv in dicCond) { if (firstRecord) firstRecord = false; else { sbData.Append(" and "); } sbData.Append("`"); sbData.Append(kv.Key); sbData.Append("` = "); sbData.Append("@c"); sbData.Append(kv.Key); } sbData.Append(";"); this._command.CommandText = sbData.ToString(); foreach (KeyValuePair kv in dicData) { this._command.Parameters.AddWithValue("@v" + kv.Key, kv.Value); } foreach (KeyValuePair kv in dicCond) { this._command.Parameters.AddWithValue("@c" + kv.Key, kv.Value); } this._command.ExecuteNonQuery(); } public long LastInsertRowId() { return ExecuteScalar("select last_insert_rowid();"); } #endregion #region 基本工具 public void CreateTable(SQLiteTable table) { StringBuilder sb = new StringBuilder(); sb.Append("create table if not exists `"); sb.Append(table.TableName); sb.AppendLine("`("); bool firstRecord = true; foreach (SQLiteColumn col in table.Columns) { if (col.ColumnName.Trim().Length == 0) { throw new Exception("Column name cannot be blank."); } if (firstRecord) firstRecord = false; else sb.AppendLine(","); sb.Append(col.ColumnName); sb.Append(" "); if (col.AutoIncrement) { sb.Append("integer primary key autoincrement"); continue; } switch (col.ColumnType) { case SQLiteColumnType.Text: sb.Append("text"); break; case SQLiteColumnType.Integer: sb.Append("integer"); break; case SQLiteColumnType.Decimal: sb.Append("decimal"); break; case SQLiteColumnType.DateTime: sb.Append("datetime"); break; case SQLiteColumnType.BLOB: sb.Append("blob"); break; } if (col.PrimaryKey) sb.Append(" primary key"); else if (col.NotNull) sb.Append(" not null"); else if (col.DefaultValue.Length > 0) { sb.Append(" default "); if (col.DefaultValue.Contains(" ") || col.ColumnType == SQLiteColumnType.Text || col.ColumnType == SQLiteColumnType.DateTime) { sb.Append("'"); sb.Append(col.DefaultValue); sb.Append("'"); } else { sb.Append(col.DefaultValue); } } } sb.AppendLine(");"); this._command.CommandText = sb.ToString(); this._command.ExecuteNonQuery(); } public void RenameTable(string tableFrom, string tableTo) { this._command.CommandText = string.Format("alter table `{0}` rename to `{1}`;", tableFrom, tableTo); this._command.ExecuteNonQuery(); } public void CopyAllData(string tableFrom, string tableTo) { DataTable dt1 = Select(string.Format("select * from `{0}` where 1 = 2;", tableFrom)); DataTable dt2 = Select(string.Format("select * from `{0}` where 1 = 2;", tableTo)); Dictionary dic = new Dictionary(); foreach (DataColumn dc in dt1.Columns) { if (dt2.Columns.Contains(dc.ColumnName)) { if (!dic.ContainsKey(dc.ColumnName)) { dic[dc.ColumnName] = true; } } } foreach (DataColumn dc in dt2.Columns) { if (dt1.Columns.Contains(dc.ColumnName)) { if (!dic.ContainsKey(dc.ColumnName)) { dic[dc.ColumnName] = true; } } } StringBuilder sb = new StringBuilder(); foreach (KeyValuePair kv in dic) { if (sb.Length > 0) sb.Append(","); sb.Append("`"); sb.Append(kv.Key); sb.Append("`"); } StringBuilder sb2 = new StringBuilder(); sb2.Append("insert into `"); sb2.Append(tableTo); sb2.Append("`("); sb2.Append(sb.ToString()); sb2.Append(") select "); sb2.Append(sb.ToString()); sb2.Append(" from `"); sb2.Append(tableFrom); sb2.Append("`;"); this._command.CommandText = sb2.ToString(); this._command.ExecuteNonQuery(); } public void DropTable(string table) { this._command.CommandText = string.Format("drop table if exists `{0}`", table); this._command.ExecuteNonQuery(); } public void UpdateTableStructure(string targetTable, SQLiteTable newStructure) { newStructure.TableName = targetTable + "_temp"; CreateTable(newStructure); CopyAllData(targetTable, newStructure.TableName); DropTable(targetTable); RenameTable(newStructure.TableName, targetTable); } public void AttachDatabase(string database, string alias) { Execute(string.Format("attach '{0}' as {1};", database, alias)); } public void DetachDatabase(string alias) { Execute(string.Format("detach {0};", alias)); } public void Dispose() { this._command.Dispose(); this._command = null; } #endregion } }