343 lines
13 KiB
C#
343 lines
13 KiB
C#
using iFileProxy.Config;
|
|
using Serilog;
|
|
using System.Data;
|
|
using System.Text.Json;
|
|
using MySql.Data.MySqlClient;
|
|
using iFileProxy.Models;
|
|
using Newtonsoft.Json;
|
|
|
|
namespace iFileProxy.Helpers
|
|
{
|
|
public class DatabaseHelper
|
|
{
|
|
Database _db;
|
|
AppConfig _appConfig;
|
|
private readonly static Serilog.ILogger _logger = Log.Logger.ForContext<DatabaseHelper>();
|
|
|
|
Dictionary<string, DB> _dbDictionary = [];
|
|
|
|
public DatabaseHelper(AppConfig appConfig)
|
|
{
|
|
_logger.Information("Initializing DatabaseHelper...");
|
|
_db = appConfig.Database;
|
|
_appConfig = appConfig;
|
|
try
|
|
{
|
|
_logger.Information("Done.");
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
_logger.Fatal($"程序异常: {e.Message}");
|
|
}
|
|
LoadDbDict();
|
|
}
|
|
|
|
/// <summary>
|
|
/// 加载数据库描述字典
|
|
/// </summary>
|
|
public void LoadDbDict()
|
|
{
|
|
foreach (DB item in _db.Databases)
|
|
{
|
|
_dbDictionary.Add(item.Description, item);
|
|
_logger.Debug($"Db Config: {item.Description} <=> {item.DatabaseName} Loaded.");
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// 获取一个指定数据库的连接
|
|
/// </summary>
|
|
/// <param name="db_desc">数据库描述字段 对应AppConfig的description字段</param>
|
|
/// <returns></returns>
|
|
/// <exception cref="Exception">若某些不允许为空的字段出现空值 则抛出此异常</exception>
|
|
///
|
|
public MySqlConnection GetAndOpenDBConn(string db_desc)
|
|
{
|
|
if (!_dbDictionary.TryGetValue(db_desc, out DB Db))
|
|
{
|
|
throw new Exception($"未找到与 {db_desc} 相匹配的数据库配置");
|
|
}
|
|
|
|
var db_user = Db.User ?? _db.Common.User;
|
|
var db_password = Db.Password ?? _db.Common.Password;
|
|
var db_host = Db.Host ?? _db.Common.Host;
|
|
var db_port = Db.Port ?? _db.Common.Port;
|
|
|
|
if (db_user == null || db_password == null || db_host == null || db_port == null)
|
|
throw new NoNullAllowedException("数据库配置获取失败,不允许为空的字段出现空值");
|
|
|
|
string db_connstr = $"server={db_host};user={db_user};database={Db.DatabaseName};port={db_port};password={db_password};Pooling=true;MaximumPoolSize=500;";
|
|
MySqlConnection conn;
|
|
try
|
|
{
|
|
conn = new MySqlConnection(db_connstr);
|
|
conn.Open();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.Fatal($"获取Mysql连接时出现异常:{ex.Message}");
|
|
throw;
|
|
}
|
|
return conn;
|
|
}
|
|
|
|
public bool TestDbConfig()
|
|
{
|
|
foreach (var db in _dbDictionary)
|
|
{
|
|
_logger.Information($"[程序启动前配置验证] 正在测试数据库配置: {db.Key} ...");
|
|
MySqlConnection dbConn = new();
|
|
try
|
|
{
|
|
dbConn = GetAndOpenDBConn(db.Key);
|
|
_logger.Information($"succ.");
|
|
}
|
|
catch (Exception)
|
|
{
|
|
_logger.Fatal($"=========== 数据库: {db.Key} 测试失败! ===========");
|
|
return false;
|
|
}
|
|
finally
|
|
{
|
|
dbConn.Close();
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取一个json格式的数据表
|
|
/// </summary>
|
|
/// <param name="sql"></param>
|
|
/// <param name="conn"></param>
|
|
/// <returns></returns>
|
|
public static string QueryTableData(MySqlCommand sqlCmd)
|
|
{
|
|
DataTable dataTable = new();
|
|
using (MySqlDataAdapter adapter = new (sqlCmd))
|
|
adapter.Fill(dataTable);
|
|
return JsonConvert.SerializeObject(dataTable);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取一个json格式的数据表
|
|
/// </summary>
|
|
/// <param name="sql"></param>
|
|
/// <param name="conn"></param>
|
|
/// <returns></returns>
|
|
public string QueryTableData(string sql,string dbConfName)
|
|
{
|
|
DataTable dataTable = new();
|
|
using (MySqlDataAdapter adapter = new(new MySqlCommand(sql,GetAndOpenDBConn(dbConfName))))
|
|
adapter.Fill(dataTable);
|
|
return JsonConvert.SerializeObject(dataTable);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 内部查询数据专用 当此方法暴露给C端可能造成sql注入等安全问题
|
|
/// </summary>
|
|
/// <param name="sql">SQL语句</param>
|
|
/// <param name="dbConfName">配置文件中的Description字段</param>
|
|
/// <returns>影响的行数</returns>
|
|
public int Query(string sql, string dbConfName)
|
|
{
|
|
using MySqlCommand sqlCmd = new (sql, GetAndOpenDBConn(dbConfName));
|
|
int n = sqlCmd.ExecuteNonQuery();
|
|
_logger.Debug($"查询完成, 受影响的行数: {n}");
|
|
return n;
|
|
}
|
|
|
|
public string GetTaskListByIP(string ipAddr)
|
|
{
|
|
string sql = $"SELECT * FROM t_tasks_info WHERE client_ip = @ip_addr";
|
|
MySqlConnection conn = GetAndOpenDBConn("iFileProxy_Db");
|
|
try
|
|
{
|
|
using MySqlCommand sqlCmd = new (sql,conn);
|
|
sqlCmd.Parameters.AddWithValue("@ip_addr", ipAddr);
|
|
return QueryTableData(sqlCmd);
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
_logger.Error($"无法获取任务列表: {e.Message}");
|
|
throw;
|
|
}
|
|
finally { conn.Close(); }
|
|
}
|
|
public string GetTaskInfoByTid(string tid)
|
|
{
|
|
string sql = $"SELECT * FROM t_tasks_info WHERE `tid` =@tid";
|
|
MySqlConnection conn = GetAndOpenDBConn("iFileProxy_Db");
|
|
try
|
|
{
|
|
using MySqlCommand sqlCmd = new(sql, conn);
|
|
sqlCmd.Parameters.AddWithValue("@tid", tid);
|
|
return QueryTableData(sqlCmd);
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
_logger.Error($"无法获取任务信息: {e.Message}");
|
|
throw;
|
|
}
|
|
finally { conn.Close(); }
|
|
}
|
|
|
|
public TaskInfo? QueryTaskInfo(string fileName, string url, long size, TaskState status)
|
|
{
|
|
string sql = $"SELECT * FROM t_tasks_info WHERE url = @url AND size = @size AND `status` = @status AND file_name = @fileName";
|
|
MySqlConnection conn = GetAndOpenDBConn("iFileProxy_Db");
|
|
try {
|
|
MySqlCommand sqlCmd = new MySqlCommand(sql, conn);
|
|
sqlCmd.Parameters.AddWithValue("@url", url);
|
|
sqlCmd.Parameters.AddWithValue("@size", size);
|
|
sqlCmd.Parameters.AddWithValue("@status", status);
|
|
sqlCmd.Parameters.AddWithValue("@fileName", fileName);
|
|
string result = QueryTableData(sqlCmd);
|
|
List<TaskInfo>? r = JsonConvert.DeserializeObject<List<TaskInfo>>(result);
|
|
if (r != null)
|
|
{
|
|
return r[0];
|
|
}
|
|
else
|
|
return null;
|
|
}
|
|
catch (Exception e){
|
|
return null;
|
|
}
|
|
finally {
|
|
conn.Close();
|
|
}
|
|
|
|
}
|
|
|
|
public bool InsertTaskData(TaskInfo taskInfo)
|
|
{
|
|
_logger.Debug(System.Text.Json.JsonSerializer.Serialize(taskInfo));
|
|
string sql = "INSERT INTO `t_tasks_info` (`tid`, `file_name`, `client_ip`, `add_time`, `update_time`, `status`, `url`, `size`, `hash`, `tag`) " +
|
|
"VALUES (@tid, @file_name, @client_ip, @add_time, @update_time, @status, @url, @size, @hash, @tag)";
|
|
MySqlConnection conn = GetAndOpenDBConn("iFileProxy_Db");
|
|
|
|
try
|
|
{
|
|
using MySqlCommand sqlCmd = new(sql, conn);
|
|
sqlCmd.Parameters.AddWithValue("@tid", taskInfo.TaskId);
|
|
sqlCmd.Parameters.AddWithValue("@file_name", taskInfo.FileName);
|
|
sqlCmd.Parameters.AddWithValue("@client_ip", taskInfo.ClientIp);
|
|
sqlCmd.Parameters.AddWithValue("@add_time", taskInfo.AddTime.ToString("yyyy-MM-dd HH:mm:ss"));
|
|
sqlCmd.Parameters.AddWithValue("@update_time", taskInfo.UpdateTime.ToString("yyyy-MM-dd HH:mm:ss"));
|
|
sqlCmd.Parameters.AddWithValue("@status", taskInfo.Status);
|
|
sqlCmd.Parameters.AddWithValue("@url", taskInfo.Url);
|
|
sqlCmd.Parameters.AddWithValue("@size", taskInfo.Size);
|
|
sqlCmd.Parameters.AddWithValue("@hash", taskInfo.Hash);
|
|
sqlCmd.Parameters.AddWithValue("@tag", taskInfo.Tag);
|
|
|
|
sqlCmd.ExecuteNonQuery();
|
|
}
|
|
catch (Exception)
|
|
{
|
|
_logger.Fatal($"插入数据时出现问题");
|
|
throw;
|
|
}
|
|
finally
|
|
{
|
|
conn.Close();
|
|
}
|
|
return true;
|
|
}
|
|
public bool UpdateFieldsData(string fieldsName, string key,string val)
|
|
{
|
|
string sql = $"UPDATE t_tasks_info set `{fieldsName}` = @Data WHERE `tid` = @tid";
|
|
MySqlConnection conn = GetAndOpenDBConn("iFileProxy_Db");
|
|
try
|
|
{
|
|
using MySqlCommand sqlCmd = new(sql, conn);
|
|
sqlCmd.Parameters.AddWithValue("@Data",val);
|
|
sqlCmd.Parameters.AddWithValue("@tid",key);
|
|
if (sqlCmd.ExecuteNonQuery() == 1)
|
|
{
|
|
return true;
|
|
}
|
|
else
|
|
return false;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
_logger.Fatal($"Task Data update error.");
|
|
throw;
|
|
}
|
|
finally
|
|
{
|
|
conn.Close();
|
|
}
|
|
|
|
}
|
|
|
|
public bool UpdateTaskStatus(TaskInfo taskInfo)
|
|
{
|
|
string sql = @"UPDATE t_tasks_info set `status` = @status , update_time = Now() WHERE `tid` = @tid";
|
|
MySqlConnection conn = GetAndOpenDBConn("iFileProxy_Db");
|
|
try
|
|
{
|
|
using MySqlCommand sqlCmd = new (sql, conn);
|
|
sqlCmd.Parameters.AddWithValue("@status", taskInfo.Status);
|
|
sqlCmd.Parameters.AddWithValue("@tid", taskInfo.TaskId);
|
|
if (sqlCmd.ExecuteNonQuery() >= 1)
|
|
{
|
|
_logger.Debug($"Task: {taskInfo.TaskId} Status Change to {taskInfo.Status}");
|
|
return true;
|
|
}
|
|
else
|
|
_logger.Warning($"Task: {taskInfo.TaskId} Status Change Failed.");
|
|
return false;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
_logger.Fatal($"Task status update error.");
|
|
throw;
|
|
}
|
|
finally
|
|
{
|
|
conn.Close ();
|
|
}
|
|
}
|
|
|
|
public bool UpdateTaskHash(TaskInfo taskInfo)
|
|
{
|
|
return UpdateFieldsData("hash", taskInfo.TaskId, MasterHelper.GetFileHash(Path.Combine(_appConfig.DownloadOptions.SavePath, taskInfo.FileName), FileHashAlgorithm.MD5));
|
|
}
|
|
|
|
public void TryInitialDB()
|
|
{
|
|
string sql = """
|
|
CREATE TABLE `t_tasks_info` (
|
|
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '自增键',
|
|
`tid` varchar(48) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '任务id',
|
|
`file_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
|
|
`client_ip` varchar(15) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '客户端IP',
|
|
`add_time` datetime NOT NULL COMMENT '任务在何时被添加',
|
|
`update_time` datetime NOT NULL COMMENT '任务状态更新时间',
|
|
`status` int(11) NULL DEFAULT NULL COMMENT '任务状态',
|
|
`url` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '文件url',
|
|
`size` int(11) NULL DEFAULT NULL COMMENT '文件大小',
|
|
`hash` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '文件hash',
|
|
PRIMARY KEY (`id`) USING BTREE
|
|
) ENGINE = InnoDB AUTO_INCREMENT = 17 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
|
|
""";
|
|
MySqlConnection conn = GetAndOpenDBConn("iFileProxy_Db");
|
|
|
|
try
|
|
{
|
|
using MySqlCommand cmd = new(sql, conn);
|
|
cmd.ExecuteNonQuery();
|
|
}
|
|
catch (Exception)
|
|
{
|
|
_logger.Error($"Db Init Fai.l");
|
|
throw;
|
|
}
|
|
finally
|
|
{
|
|
conn.Close();
|
|
}
|
|
}
|
|
}
|
|
}
|