Commit db2a11fc authored by 潘栩锋's avatar 潘栩锋 🚴

删除 SQLiteHelper

parent 7438b8f6
Pipeline #110 failed with stages
# SQLiteRemote
sqlite 局域网远程访问
\ No newline at end of file
sqlite 局域网远程访问
远程代理 是基于 WSCF (WebSocket Communication Foundation) 建立的
WSCF 项目:http://private.flyautomation.net:82/panruising/wscf.git
## RemoteSQLite
**项目主体**
ISQLiteRemoteService *SQLite服务代理*<br/>
ISysTimeService *系统时间*<br/>
## SQLiteRemoteServerUI
**SQLite服务代理**
<br/>
SQLiteRemoteServerUI 只是 RemoteSQLite.RemoteSQLiteServer 的外壳。<br/>
使用方法:<br/>
放在 ###.sqlite3 文件 那台电脑上运行。 <br/>
<br/>
它提供2个服务<br/>
/SQLiteRemote *SQLite操作*
1. ExecuteReader
2. ExecuteNonQuery
3. ExecuteScalar
/SysTime *系统时间操作*
1. Now
2. SetTime *通过网络延时比较准确设置时间*
3. GetTime
## SQLiteRemoteClientUI
**SQLiteRemoteServiceClient 的测试**
<?xml version="1.0" encoding="utf-8"?>
<configuration>
</configuration>
\ No newline at end of file
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
namespace SQLite
{
public class DBTable<T> : IDBTable
where T : new()
{
public string TableName { get; private set; }
private long freeID = 0;
/// <summary>
/// 每次获取,自动++
/// </summary>
public long FreeID
{
get
{
return freeID++;
}
set {
freeID = value;
}
}
private string ddl;
public string DDL
{
get
{
return ddl;
}
}
public SQLiteHelper sqliteHelper;
public DBTable()
{
TableName = SQLiteHelper.GetTableName(typeof(T));
ddl = SQLiteHelper.GetCreateTableCommandText(typeof(T));
}
public void Init(SQLiteHelper sQLiteHelper)
{
sqliteHelper = sQLiteHelper;
}
public void Create()
{
sqliteHelper.ExecuteNonQuery(ddl);// SQLiteHelper.GetCreateTableCommandText(typeof(T)));//, ArrayFieldTypeInfos.ToArray()));
}
public void Add(T t)
{
sqliteHelper.ExecuteNonQuery(SQLiteHelper.GetInsertCommandText(t));
}
public void Update(T t, string condition)
{
sqliteHelper.ExecuteNonQuery(SQLiteHelper.GetUpdateCommandText(t, condition));
}
public bool AddRange(IEnumerable<T> array)
{
List<string> querys = new List<string>();
foreach (T t in array)
{
querys.Add(SQLiteHelper.GetInsertCommandText(t));
}
return sqliteHelper.QueryTran(querys);
}
public List<T> Find(string condition)
{
string sql = $"SELECT * FROM {TableName}";
if (!string.IsNullOrEmpty(condition))
sql += " " + condition;
DataTable dataTable = sqliteHelper.ExecuteReader(sql);
return SQLiteHelper.ToObjs<T>(dataTable);
}
/// <summary>
/// 获取最后N行数据
/// </summary>
/// <param name="count"></param>
/// <returns></returns>
public List<T> Last(int count)
{
return Find($"LIMIT (SELECT COUNT()-{count} FROM {TableName}),{count}");
}
/// <summary>
/// 获取前面N行数据
/// </summary>
/// <param name="count"></param>
/// <returns></returns>
public List<T> First(int count)
{
return Find($"LIMIT {count}");
}
public void Remove()
{
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace SQLite
{
public interface IDBTable
{
/// <summary>
/// 表名
/// </summary>
string TableName { get; }
/// <summary>
/// 表的 Create SQL
/// </summary>
string DDL { get; }
/// <summary>
/// 创建表
/// </summary>
void Create();
long FreeID { get; set; }
/// <summary>
/// 初始化
/// </summary>
/// <param name="sQLiteHelper"></param>
void Init(SQLiteHelper sQLiteHelper);
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SQLite
{
public interface IDbBase
{
Int64 ID { get; set; }
}
}

using System;
namespace SQLite
{
public class IgnoreAttribute : Attribute
{
public IgnoreAttribute()
{
}
}
public class PropertyIndexAttribute : Attribute
{
/// <summary>
/// 标识
/// </summary>
public int Index { get; set; }
/// <summary>
///
/// </summary>
/// <param name="index"></param>
public PropertyIndexAttribute(int index)
{
Index = index;
}
}
}
\ No newline at end of file
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// 有关程序集的一般信息由以下
// 控制。更改这些特性值可修改
// 与程序集关联的信息。
[assembly: AssemblyTitle("SQLiteHelper")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("SQLiteHelper")]
[assembly: AssemblyCopyright("Copyright © 2019")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// 将 ComVisible 设置为 false 会使此程序集中的类型
//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型
//请将此类型的 ComVisible 特性设置为 true。
[assembly: ComVisible(false)]
// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
[assembly: Guid("4cbabfaa-1c62-4510-ac63-a51ee5fd50ff")]
// 程序集的版本信息由下列四个值组成:
//
// 主版本
// 次版本
// 生成号
// 修订号
//
// 可以指定所有值,也可以使用以下所示的 "*" 预置版本号和修订号
//通过使用 "*",如下所示:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
using System;
using System.Collections.Generic;
using System.Data.SQLite;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SQLite
{
public abstract class SQLiteDbContext
{
public List<IDBTable> DbSet = new List<IDBTable>();
public SQLiteHelper sqliteHelper { get; private set; }
string ConnectionString
{
get
{
return string.Format("Data Source={0};Version=3;", DBPath);
}
}
public string DBPath { get; private set; } = @"test.sqlite3";
public SQLiteDbContext(string dbPath)
{
DBPath = dbPath;
Constructor();
}
void Constructor()
{
sqliteHelper = new SQLiteHelper();
sqliteHelper.ConnectionString = ConnectionString;
var type = GetType();
foreach (var p in type.GetProperties())
{
if (typeof(IDBTable).IsAssignableFrom(p.PropertyType))
{
DbSet.Add(p.GetValue(this) as IDBTable);
}
}
foreach (IDBTable dBTable in DbSet)
{
dBTable.Init(sqliteHelper);
}
}
public void SetDBPath(string dbPath)
{
DBPath = dbPath;
sqliteHelper.ConnectionString = ConnectionString;
}
void Build()
{
string directoryname = System.IO.Path.GetDirectoryName(DBPath);
if (!string.IsNullOrEmpty(directoryname) && !System.IO.Directory.Exists(directoryname))
System.IO.Directory.CreateDirectory(directoryname);
SQLiteConnection.CreateFile(DBPath);
foreach (IDBTable dBTable in DbSet)
dBTable.Create();
}
void Rebuild()
{
if (!System.IO.File.Exists(DBPath))
{
Build();
}
else
{
//把文件删除,重建
System.IO.File.Delete(DBPath);
Build();
}
}
void Load()
{
foreach(var table in DbSet)
{
table.FreeID = LoadID(table.TableName);
}
}
long LoadID(string tablename)
{
string cmd = $"SELECT MAX(ID) FROM {tablename}";
var reponse = sqliteHelper.ExecuteScalar(cmd);
if (reponse is DBNull)
return 0;
else
return System.Convert.ToInt64(reponse) + 1;
}
/// <summary>
/// 给定分区数 检测表是否存在,合法
/// </summary>
/// <param name="nbolts"></param>
/// <returns>false 表不合法,重建; true 正常!</returns>
public bool Init()
{
if (!System.IO.File.Exists(DBPath))
{
Build();
return false;
}
//TODO, 表不对删除就好。。。没必要重新创建数据库
//任意一个表不对,或者不存在,都必须重建
Dictionary<string, string> ddls = new Dictionary<string, string>();
foreach (IDBTable tb in DbSet)
{
ddls.Add(tb.TableName, tb.DDL);
}
bool isVaild = sqliteHelper.IsTableValid(ddls, out Dictionary<string, SQLiteHelper.IsTableValidResult> results);
if (!isVaild)//不合法
{
if (results.Any(kv => kv.Value == SQLiteHelper.IsTableValidResult.FormatErr))
{
//先备份
File.Copy(DBPath, DBPath + $".{DateTime.Now:yyyyMMddHHmmss}.bk");
}
//有表 不对
foreach (var kv in results)
{
switch (kv.Value)
{
case SQLiteHelper.IsTableValidResult.NotHere:
{
//直接创建表
sqliteHelper.ExecuteNonQuery(ddls[kv.Key]);
}
break;
case SQLiteHelper.IsTableValidResult.FormatErr:
{
//先删除表,再创建
sqliteHelper.ExecuteNonQuery($"DROP TABLE {kv.Key}");
sqliteHelper.ExecuteNonQuery(ddls[kv.Key]);
}
break;
}
}
}
//最后也要加载数据
Load();
return isVaild;
}
/// <summary>
/// 当出错,不重建表
/// </summary>
/// <returns></returns>
public bool InitNoBuild()
{
if (!System.IO.File.Exists(DBPath))
{
Build();
return false;
}
//TODO, 表不对删除就好。。。没必要重新创建数据库
//任意一个表不对,或者不存在,都必须重建
Dictionary<string, string> ddls = new Dictionary<string, string>();
foreach (IDBTable tb in DbSet)
{
ddls.Add(tb.TableName, tb.DDL);
}
if (sqliteHelper.IsTableValid(ddls))
{
Load();
return true;
}
else
{
return false;
}
}
}
}
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data;
using System.Data.SQLite;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
namespace SQLite
{
public class SQLiteHelper
{
static NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
#region 静态操作
public class SQLiteFieldTypeInfo
{
/// <summary>
/// sqlite field 类型
/// </summary>
public string FieldType { get; set; }
/// <summary>
/// C# 类型
/// </summary>
public Type PropertyType { get; set; }
/// <summary>
/// C# 类型转 sqlite 字符串
/// </summary>
public Func<object, string> PtoS { get; set; } = DefaultToS;
public Func<object, object> StoP { get; set; } = DefaultToP;
public static string DefaultToS(object obj)
{
return obj.ToString();
}
public static object DefaultToP(object obj)
{
return obj;
}
public SQLiteFieldTypeInfo(string fieldtype, Type propertytype)
{
FieldType = fieldtype;
PropertyType = propertytype;
}
public SQLiteFieldTypeInfo(string fieldtype, Type propertytype, Func<object, string> ptos, Func<object, object> stop)
{
FieldType = fieldtype;
PropertyType = propertytype;
PtoS = ptos;
StoP = stop;
}
}
public static List<SQLiteFieldTypeInfo> FieldTypeInfo { get; set; }
static SQLiteHelper()
{
FieldTypeInfo = new List<SQLiteFieldTypeInfo>
{
new SQLiteFieldTypeInfo("INTEGER",typeof(int),
SQLiteFieldTypeInfo.DefaultToS,
(obj)=>{
return Convert.ToInt32(obj);
}
),
new SQLiteFieldTypeInfo("INTEGER",typeof(int?),
SQLiteFieldTypeInfo.DefaultToS,
(obj)=>{
if(obj is DBNull)
return null;
else
return Convert.ToInt32(obj);
}
),
new SQLiteFieldTypeInfo("INTEGER",typeof(Int64)),
new SQLiteFieldTypeInfo("INTEGER",typeof(Int64?),
SQLiteFieldTypeInfo.DefaultToS,
(obj)=>{
if(obj is DBNull)
return null;
else
return Convert.ToInt64(obj);
}
),
new SQLiteFieldTypeInfo("BOOLEAN",typeof(bool)),
new SQLiteFieldTypeInfo("BOOLEAN",typeof(bool?),
SQLiteFieldTypeInfo.DefaultToS,
(obj)=>{
if(obj is DBNull)
return null;
else
return Convert.ToBoolean(obj);
}
),
new SQLiteFieldTypeInfo("DOUBLE",typeof(double),
(obj)=>((double)obj).ToStringOfSQLiteFieldType(),
(obj)=>{
if(obj == DBNull.Value)
return double.NaN;
else
return obj;
}
),
new SQLiteFieldTypeInfo("TEXT",typeof(string),
(obj)=>((string)obj).ToStringOfSQLiteFieldType(),
SQLiteFieldTypeInfo.DefaultToP
),
new SQLiteFieldTypeInfo("DATETIME",typeof(DateTime),
(obj)=>((DateTime)obj).ToStringOfSQLiteFieldType(),
SQLiteFieldTypeInfo.DefaultToP
)
};
}
public static SQLiteFieldTypeInfo GetFieldTypeInfo(string fieldtype)
{
var ftis = from fti in FieldTypeInfo where fti.FieldType == fieldtype select fti;
if (ftis.Count() > 0)
{
return ftis.First();
}
else
{
return null;
}
}
public static string GetTableName(Type type)
{
var attributes = type.GetCustomAttributes(typeof(TableAttribute), false);
if (attributes.Count() > 0)
{
return ((TableAttribute)attributes.First()).Name;
}
else
{
return type.Name;
}
}
static string GetCreateTableCommandText_fieldText(Type type)
{
string total_fieldtext = "";
List<FieldTextIndex> fieldTexts = new List<FieldTextIndex>();
PropertyInfo[] propertyInfos = type.GetProperties();
foreach (var propertyInfo in propertyInfos)
{
//忽略
if (propertyInfo.GetCustomAttributes(typeof(IgnoreAttribute), false).Count() > 0)
continue;
FieldTextIndex fieldText = new FieldTextIndex();
fieldTexts.Add(fieldText);
PropertyIndexAttribute propertyIndex = propertyInfo.GetCustomAttribute(typeof(PropertyIndexAttribute)) as PropertyIndexAttribute;
if (propertyIndex != null)
fieldText.index = propertyIndex.Index;//默认index=0
SQLiteFieldTypeInfo fieldTypeInfo = FieldTypeInfo.Find((fti) => fti.PropertyType == propertyInfo.PropertyType);
string text = "";
text += string.Format("{0} {1}", propertyInfo.Name, fieldTypeInfo.FieldType);
//主键
if (propertyInfo.GetCustomAttributes(typeof(KeyAttribute), false).Count() > 0)
text += " PRIMARY KEY";
fieldText.fieldtext = text;
}
//从小到大排序
fieldTexts.Sort((fieldTextIndex0, fieldTextIndex1) =>
{
if (fieldTextIndex0.index < fieldTextIndex1.index)
return -1;
if (fieldTextIndex0.index > fieldTextIndex1.index)
return 1;
else
return 0;
});
for (int i = 0; i < fieldTexts.Count(); i++)
{
var fieldTextIndex = fieldTexts[i];
if (i != 0)
total_fieldtext += ",";
total_fieldtext += fieldTextIndex.fieldtext;
}
return total_fieldtext;
}
public static string GetCreateTableCommandText(Type type)
{
//CREATE TABLE table_name(
//column1 datatype PRIMARY KEY,
//column2 datatype,
// column3 datatype,
// .....
// columnN datatype,
//)
string tablename = GetTableName(type);
string fieldtext = GetCreateTableCommandText_fieldText(type);
string commandText = string.Format("CREATE TABLE {0} ({1})", tablename, fieldtext);
return commandText;
}
class FieldTextIndex
{
public int index = 0;
public string fieldtext = "";
}
static string GetInsertCommandText_fieldText(object cell)
{
Type type = cell.GetType();
string total_fieldtext = "";
List<FieldTextIndex> fieldTexts = new List<FieldTextIndex>();
PropertyInfo[] propertyInfos = type.GetProperties();
foreach (var propertyInfo in propertyInfos)
{
//忽略
if (propertyInfo.GetCustomAttributes(typeof(IgnoreAttribute), false).Count() > 0)
continue;
FieldTextIndex fieldText = new FieldTextIndex();
fieldTexts.Add(fieldText);
PropertyIndexAttribute propertyIndex = propertyInfo.GetCustomAttribute(typeof(PropertyIndexAttribute)) as PropertyIndexAttribute;
if (propertyIndex != null)
fieldText.index = propertyIndex.Index;//默认index=0
object o = propertyInfo.GetValue(cell, null);
SQLiteFieldTypeInfo fieldTypeInfo = FieldTypeInfo.Find((fti) => fti.PropertyType == propertyInfo.PropertyType);
fieldText.fieldtext = fieldTypeInfo.PtoS(o);
}
//从小到大排序
fieldTexts.Sort((fieldTextIndex0, fieldTextIndex1) =>
{
if (fieldTextIndex0.index < fieldTextIndex1.index)
return -1;
if (fieldTextIndex0.index > fieldTextIndex1.index)
return 1;
else
return 0;
});
for (int i = 0; i < fieldTexts.Count(); i++)
{
var fieldTextIndex = fieldTexts[i];
if (i != 0)
total_fieldtext += ",";
total_fieldtext += fieldTextIndex.fieldtext;
}
return total_fieldtext;
}
public static string GetInsertCommandText(object cell)
{
//不用
//INSERT INTO TABLE_NAME[(column1, column2, column3,...columnN)]
//VALUES(value1, value2, value3,...valueN);
//使用
//INSERT INTO TABLE_NAME VALUES(value1, value2, value3,...valueN);
Type type = cell.GetType();
string tablename = GetTableName(type);
string fieldtext = GetInsertCommandText_fieldText(cell);
string commandText = string.Format("INSERT INTO {0} VALUES({1})", tablename, fieldtext);
return commandText;
}
static string GetUpdateCommandText_fieldText(object cell)
{
//UPDATE table_name
//SET column1 = value1, column2 = value2...., columnN = valueN
//WHERE[condition];
Type type = cell.GetType();
string tablename = GetTableName(type);
string fieldtext = "";
PropertyInfo[] propertyInfos = type.GetProperties();
foreach (var propertyInfo in propertyInfos)
{
//忽略
if (propertyInfo.GetCustomAttributes(typeof(IgnoreAttribute), false).Count() > 0)
continue;
if (fieldtext != "")
{
fieldtext += ",";
}
object o = propertyInfo.GetValue(cell, null);
SQLiteFieldTypeInfo fieldTypeInfo = FieldTypeInfo.Find((fti) => fti.PropertyType == propertyInfo.PropertyType);
fieldtext += string.Format("{0} = {1}", propertyInfo.Name, fieldTypeInfo.PtoS(o));
}
return fieldtext;
}
/// <summary>
/// condition 为 "WHERE ......"
/// </summary>
/// <param name="cell"></param>
/// <param name="condition"></param>
/// <returns></returns>
public static string GetUpdateCommandText(object cell, string condition)
{
//UPDATE table_name
//SET column1 = value1, column2 = value2...., columnN = valueN
//WHERE[condition];
Type type = cell.GetType();
string tablename = GetTableName(type);
string fieldtext = GetUpdateCommandText_fieldText(cell);
string commandText = $"UPDATE {tablename} SET {fieldtext}";
if (!string.IsNullOrEmpty(condition))
commandText += $" {condition}";
return commandText;
}
public static List<T> ToObjs<T>(DataTable dataTable)
where T : new()
{
List<T> list = new List<T>();
foreach (DataRow dataRow in dataTable.Rows)
{
list.Add(ToObj<T>(dataRow));
}
return list;
}
static void SetObj(object t, DataRow dataRow)
{
Type type = t.GetType();
PropertyInfo[] propertyInfos = type.GetProperties();
foreach (var propertyInfo in propertyInfos)
{
//忽略
if (propertyInfo.GetCustomAttributes(typeof(IgnoreAttribute), false).Count() > 0)
continue;
Type ptype = propertyInfo.PropertyType;
SQLiteFieldTypeInfo fieldTypeInfo = FieldTypeInfo.Find((fti) => fti.PropertyType == ptype);
object o = fieldTypeInfo.StoP(dataRow[propertyInfo.Name]);
propertyInfo.SetValue(t, o, null);
}
}
public static T ToObj<T>(DataRow dataRow)
where T : new()
{
T t = new T();
SetObj(t, dataRow);
return t;
}
#endregion
public string ConnectionString;
/// <summary>
/// 查询数据库中的所有数据类型信息。
/// </summary>
/// <returns></returns>
/// <exception cref="Exception"></exception>
public DataTable ExecuteReader(string sql)
{
DataTable data;
using (SQLiteConnection connection = new SQLiteConnection(ConnectionString))
{
using (SQLiteCommand command = new SQLiteCommand(connection))
{
connection.Open();
command.CommandText = sql;
// 开始读取
SQLiteDataAdapter adapter = new SQLiteDataAdapter(command);
data = new DataTable();
adapter.Fill(data);
connection.Close();
}
}
return data;
}
/// <summary>
/// 对SQLite数据库执行增删改操作,返回受影响的行数。
/// </summary>
/// <param name="sql">要执行的增删改的SQL语句。</param>
/// <param name="parameters">执行增删改语句所需要的参数,参数必须以它们在SQL语句中的顺序为准。</param>
/// <returns></returns>
/// <exception cref="Exception"></exception>
public void ExecuteNonQuery(string sql)
{
using (SQLiteConnection connection = new SQLiteConnection(ConnectionString))
{
using (SQLiteCommand command = new SQLiteCommand(connection))
{
connection.Open();
command.CommandText = sql;
command.ExecuteNonQuery();
connection.Close();
}
}
}
/// <summary>
///
/// </summary>
/// <param name="sql"></param>
/// <returns>The first column of the first row of the first resultset from the query.</returns>
public object ExecuteScalar(string sql)
{
object obj = null;
using (SQLiteConnection connection = new SQLiteConnection(ConnectionString))
{
using (SQLiteCommand command = new SQLiteCommand(connection))
{
connection.Open();
command.CommandText = sql;
obj = command.ExecuteScalar();
connection.Close();
}
}
return obj;
}
/// <summary>
/// 多行执行
/// </summary>
/// <param name="queryList"></param>
/// <returns></returns>
public bool QueryTran(IEnumerable<string> queryList)
{
if (isHoldQueryTran)
{
holdQueryList.AddRange(queryList);
return true;
}
else
{
using (SQLiteConnection connection = new SQLiteConnection(ConnectionString))
{
using (SQLiteCommand command = new SQLiteCommand(connection))
{
connection.Open();
SQLiteTransaction tran = connection.BeginTransaction();
bool check = false;
try
{
foreach (string item in queryList)
{
command.CommandText = item;
command.ExecuteNonQuery();
}
tran.Commit();
check = true;
}
catch (Exception ex)
{
tran.Rollback();
check = false;
logger.Error(ex, Newtonsoft.Json.JsonConvert.SerializeObject(queryList));
throw ex;
}
finally
{
connection.Close();
}
return check;
}
}
}
}
/// <summary>
/// 异步
/// </summary>
/// <param name="queryList"></param>
/// <returns></returns>
public void QueryTranAsync(IEnumerable<string> queryList)
{
new Task((obj) => {
var _sqls = obj as IEnumerable<string>;
QueryTran(_sqls);
}, queryList).Start(StepByStepTaskScheduler.Current);
}
List<string> holdQueryList = new List<string>();
bool isHoldQueryTran = false;
public void HoldQueryTran()
{
isHoldQueryTran = true;
}
public bool ReleaseQueryTran()
{
if (holdQueryList.Count() > 0)
{
using (SQLiteConnection connection = new SQLiteConnection(ConnectionString))
{
using (SQLiteCommand command = new SQLiteCommand(connection))
{
connection.Open();
SQLiteTransaction tran = connection.BeginTransaction();
bool check = false;
try
{
foreach (string item in holdQueryList)
{
command.CommandText = item;
command.ExecuteNonQuery();
}
tran.Commit();
check = true;
}
catch (Exception ex)
{
tran.Rollback();
check = false;
throw ex;
}
finally
{
holdQueryList.Clear();
connection.Close();
isHoldQueryTran = false;
}
return check;
}
}
}
isHoldQueryTran = false;
return true;
}
/// <summary>
/// 出错代码
/// </summary>
public string ErrorMsg { get; set; }
/// <summary>
/// 输入DDLs 判断这些table都是否合法
/// </summary>
/// <param name="DDLs">key=tablename, value=DDL</param>
/// <returns></returns>
public bool IsTableValid(Dictionary<string, string> DDLs)
{
//检测 table 是否合法
DataTable data = ExecuteReader("SELECT name,sql FROM sqlite_master WHERE type = 'table'");
//任意一个表不对,或者不存在,都必须重建
bool isVaild = true;
foreach (var kv in DDLs)
{
string tablename = kv.Key;
string createtable_sql = kv.Value;
var sqls = from r in data.AsEnumerable() where (string)r["name"] == tablename select r["sql"];
if (sqls.Count() == 0)
{
//不存在该表,创建
isVaild = false;
break;
}
else
{
string sql = (string)sqls.First();
if (sql != createtable_sql)
{
if (!GetTableInfoFromDDL(sql, out SQLiteTableInfo tableInfo0))
{
ErrorMsg = $"sqlite_master 找到 name = '{tablename}' 的 sql 不能解析";
isVaild = false;
break;
}
if (!GetTableInfoFromDDL(createtable_sql, out SQLiteTableInfo tableInfo1))
{
ErrorMsg = $"程序中 name = '{tablename}' 的 sql 不能解析";
isVaild = false;
break;
}
if (!tableInfo0.Equals(tableInfo1))
{
ErrorMsg = $"sqlite_master 找到 name = '{tablename}' 的 sql 不符合要求, " + tableInfo0.ErrorMsg;
isVaild = false;
break;
}
}
}
}
return isVaild;
}
public enum IsTableValidResult
{
OK,
NotHere,
FormatErr
}
/// <summary>
/// 输入DDLs 判断这些table都是否合法
/// </summary>
/// <param name="DDLs">key=tablename, value=DDL</param>
/// <returns></returns>
public bool IsTableValid(Dictionary<string, string> DDLs,out Dictionary<string,IsTableValidResult> results)
{
results = new Dictionary<string, IsTableValidResult>();
//检测 table 是否合法
DataTable data = ExecuteReader("SELECT name,sql FROM sqlite_master WHERE type = 'table'");
//任意一个表不对,或者不存在,都必须重建
foreach (var kv in DDLs)
{
string tablename = kv.Key;
string createtable_sql = kv.Value;
var sqls = from r in data.AsEnumerable() where (string)r["name"] == tablename select r["sql"];
if (sqls.Count() == 0)
{
//不存在该表
ErrorMsg = $"sqlite_master 不能找到 name = '{tablename}' 的 sql";
results.Add(tablename, IsTableValidResult.NotHere);
continue;
}
string sql = (string)sqls.First();
if (sql == createtable_sql)
{
//完全一样
results.Add(tablename, IsTableValidResult.OK);
continue;
}
if (!GetTableInfoFromDDL(sql, out SQLiteTableInfo tableInfo0))
{
ErrorMsg = $"sqlite_master 找到 name = '{tablename}' 的 sql 不能解析";
results.Add(tablename, IsTableValidResult.FormatErr);
continue;
}
if (!GetTableInfoFromDDL(createtable_sql, out SQLiteTableInfo tableInfo1))
{
ErrorMsg = $"程序中 name = '{tablename}' 的 sql 不能解析";
results.Add(tablename, IsTableValidResult.FormatErr);
continue;
}
if (!tableInfo0.Equals(tableInfo1))
{
ErrorMsg = $"sqlite_master 找到 name = '{tablename}' 的 sql 不符合要求, " + tableInfo0.ErrorMsg;
results.Add(tablename, IsTableValidResult.FormatErr);
continue;
}
//虽然不一样,都也是合法的
results.Add(tablename, IsTableValidResult.OK);
}
return results.All(kv => kv.Value == IsTableValidResult.OK);
}
public bool GetTableInfoFromDDL(string DDL, out SQLiteTableInfo tableInfo)
{
tableInfo = null;
Regex regex_key = new Regex(@"PRIMARY KEY");
//CREATE TABLE boltmap(ID INTEGER PRIMARY KEY, MID INTEGER, RBegin INTEGER, REnd INTEGER)
Regex regex = new Regex(@"CREATE TABLE\s+(\w+)\s+\((.+)\)");
Match match = regex.Match(DDL);
if (!match.Success)
{
ErrorMsg = "不能匹配 CREATE TABLE 的格式";
return false;
}
tableInfo = new SQLiteTableInfo();
tableInfo.Name = match.Groups[1].Value;
string fields_sql = match.Groups[2].Value;
string[] fields_str = fields_sql.Split(',');
foreach (string str in fields_str)
{
SQLiteFieldInfo fieldInfo = new SQLiteFieldInfo();
string str1 = str.Trim();
string[] ss = str1.Split(' ');
if (ss.Length < 2)
{
ErrorMsg = $"{str1} 格式出错";
return false;
}
fieldInfo.Name = ss[0];
fieldInfo.Type = ss[1];
if (regex_key.IsMatch(str1))
fieldInfo.IsKey = true;
tableInfo.FieldInfos.Add(fieldInfo);
}
return true;
}
}
public class SQLiteTableInfo
{
/// <summary>
/// 名称
/// </summary>
public string Name;
public List<SQLiteFieldInfo> FieldInfos = new List<SQLiteFieldInfo>();
public override bool Equals(object obj)
{
SQLiteTableInfo tableinfo = obj as SQLiteTableInfo;
if (tableinfo.Name != Name)
{
ErrorMsg = $"名称不相等 期待.{tableinfo.Name}!=数据库.{Name}";
return false;
}
if (tableinfo.FieldInfos.Count() != FieldInfos.Count())
{
ErrorMsg = $"field 数量不同 期待.{tableinfo.FieldInfos.Count()}!=数据库.{FieldInfos.Count()}";
return false;
}
for (int i = 0; i < FieldInfos.Count(); i++)
{
if (!FieldInfos[i].Equals(tableinfo.FieldInfos[i]))
{
ErrorMsg = $"field 不同 期待.({tableinfo.FieldInfos[i]})!=数据库.({FieldInfos[i]})";
return false;
}
}
ErrorMsg = "OK";
return true;
}
public string ErrorMsg { get; set; }
}
public class SQLiteFieldInfo
{
/// <summary>
/// 类型
/// </summary>
public string Type;
/// <summary>
/// 名称
/// </summary>
public string Name;
/// <summary>
/// 是主键?
/// </summary>
public bool IsKey;
public override bool Equals(object obj)
{
SQLiteFieldInfo fieldInfo = obj as SQLiteFieldInfo;
if (Type != fieldInfo.Type)
return false;
if (Name != fieldInfo.Name)
return false;
if (IsKey != fieldInfo.IsKey)
return false;
return true;
}
public override string ToString()
{
string s = $"{Name} As {Type}";
if (IsKey)
s += " IsKey";
return s;
}
}
public static class SQLiteFieldTypeExtern
{
public static string ToStringOfSQLiteFieldType(this DateTime dt)
{
return $"'{dt:yyyy-MM-dd HH:mm:ss.fff}'";
}
public static string ToStringOfSQLiteFieldType(this string str)
{
return $"'{str}'";
}
public static string ToStringOfSQLiteFieldType(this double d)
{
if (double.IsNaN(d))
return "NULL";
else return d.ToString();
}
}
public class StepByStepTaskScheduler : TaskScheduler
{
public static new TaskScheduler Current { get; } = new StepByStepTaskScheduler();
public static new TaskScheduler Default { get; } = Current;
public static StepByStepTaskScheduler Instance { get; } = (StepByStepTaskScheduler)Current;
private readonly BlockingCollection<Task> m_queue = new BlockingCollection<Task>();
StepByStepTaskScheduler()
{
//Thread thread = new Thread(Run);
//thread.IsBackground = true;//设为为后台线程,当主线程结束时线程自动结束
//thread.Start();
Task.Factory.StartNew(Run);
}
private void Run()
{
//Console.WriteLine($"MyTaskScheduler, ThreadID: {Thread.CurrentThread.ManagedThreadId}");
Task t;
while (m_queue.TryTake(out t, System.Threading.Timeout.Infinite))
{
TryExecuteTask(t);//在当前线程执行Task
}
}
protected override IEnumerable<Task> GetScheduledTasks()
{
return m_queue;
}
public BlockingCollection<Task> ScheduledTasks
{
get { return m_queue; }
}
protected override void QueueTask(Task task)
{
m_queue.Add(task);//t.Start(MyTaskScheduler.Current)时,将Task加入到队列中
}
//当执行该函数时,程序正在尝试以同步的方式执行Task代码
protected override bool TryExecuteTaskInline(Task task, bool taskWasPreviouslyQueued)
{
return false;
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{4CBABFAA-1C62-4510-AC63-A51EE5FD50FF}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>SQLite</RootNamespace>
<AssemblyName>SQLite</AssemblyName>
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<Deterministic>true</Deterministic>
<NuGetPackageImportStamp>
</NuGetPackageImportStamp>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.ComponentModel.DataAnnotations" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="DBTable.cs" />
<Compile Include="IDbBase.cs" />
<Compile Include="IDBTable.cs" />
<Compile Include="IgnoreAttribute.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="SQLiteDbContext.cs" />
<Compile Include="SQLiteHelper.cs" />
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Newtonsoft.Json">
<Version>12.0.3</Version>
</PackageReference>
<PackageReference Include="NLog">
<Version>4.6.8</Version>
</PackageReference>
<PackageReference Include="System.Data.SQLite">
<Version>1.0.112</Version>
</PackageReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment