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.
 
 
 
 

519 lines
16 KiB

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 字段属性
/// <summary>
/// 连接符
/// </summary>
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<SQLiteParameter>());
}
public DataTable Select(string sql, Dictionary<string, object> dicParameters = null)
{
List<SQLiteParameter> lst = GetParametersList(dicParameters);
return Select(sql, lst);
}
private DataTable Select(string sql, IEnumerable<SQLiteParameter> 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<SQLiteParameter>());
}
public void Execute(string sql, Dictionary<string, object> dicParameters = null)
{
List<SQLiteParameter> lst = GetParametersList(dicParameters);
Execute(sql, lst);
}
private void Execute(string sql, IEnumerable<SQLiteParameter> 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<string, object> dicParameters = null)
{
List<SQLiteParameter> lst = GetParametersList(dicParameters);
return ExecuteScalar(sql, lst);
}
private object ExecuteScalar(string sql, IEnumerable<SQLiteParameter> 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<dataType>(string sql, Dictionary<string, object> dicParameters = null)
{
List<SQLiteParameter> lst = null;
if (dicParameters != null)
{
lst = new List<SQLiteParameter>();
foreach (KeyValuePair<string, object> kv in dicParameters)
{
lst.Add(new SQLiteParameter(kv.Key, kv.Value));
}
}
return ExecuteScalar<dataType>(sql, lst);
}
private dataType ExecuteScalar<dataType>(string sql, IEnumerable<SQLiteParameter> 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<dataType>(string sql)
{
this._command.CommandText = sql;
return (dataType)Convert.ChangeType(this._command.ExecuteScalar(), typeof(dataType));
}
private List<SQLiteParameter> GetParametersList(Dictionary<string, object> dicParameters)
{
List<SQLiteParameter> lst = new List<SQLiteParameter>();
if (dicParameters != null)
{
foreach (KeyValuePair<string, object> 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<string, object> dic)
{
StringBuilder sbCol = new System.Text.StringBuilder();
StringBuilder sbVal = new System.Text.StringBuilder();
foreach (KeyValuePair<string, object> 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<string, object> kv in dic)
{
this._command.Parameters.AddWithValue("@v" + kv.Key, kv.Value);
}
this._command.ExecuteNonQuery();
}
public void Update(string tableName, Dictionary<string, object> dicData, string colCond, object varCond)
{
Dictionary<string, object> dic = new Dictionary<string, object>();
dic[colCond] = varCond;
Update(tableName, dicData, dic);
}
public void Update(string tableName, Dictionary<string, object> dicData, Dictionary<string, object> dicCond)
{
if (dicData.Count == 0)
throw new Exception("dicData is empty.");
StringBuilder sbData = new System.Text.StringBuilder();
Dictionary<string, object> _dicTypeSource = new Dictionary<string, object>();
foreach (KeyValuePair<string, object> kv1 in dicData)
{
_dicTypeSource[kv1.Key] = null;
}
foreach (KeyValuePair<string, object> 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<string, object> 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<string, object> 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<string, object> kv in dicData)
{
this._command.Parameters.AddWithValue("@v" + kv.Key, kv.Value);
}
foreach (KeyValuePair<string, object> kv in dicCond)
{
this._command.Parameters.AddWithValue("@c" + kv.Key, kv.Value);
}
this._command.ExecuteNonQuery();
}
public long LastInsertRowId()
{
return ExecuteScalar<long>("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<string, bool> dic = new Dictionary<string, bool>();
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<string, bool> 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
}
}