feat: initial commit - HJHA game server full source
6 major server modules (PdkFriendServer/GlobalSever/ServerCore/GameModule/GameNetModule) + game logic (GameFix/GameDAL/ServerData) + network layer (NetWorkMessage) + data layer (ObjectModel) + utilities (MrWu/Core/Config/CloudAPI/dll) + adapters (zyxAdapter/base) .NET 8.0 C# solution, 16 projects, 958 source files
This commit is contained in:
600
MrWu/DB/MMSSQL.cs
Normal file
600
MrWu/DB/MMSSQL.cs
Normal file
@ -0,0 +1,600 @@
|
||||
/*
|
||||
* 由SharpDevelop创建。
|
||||
* 用户:吴隆健
|
||||
* 日期: 2019-03-21
|
||||
* 时间: 10:07
|
||||
*
|
||||
*/
|
||||
|
||||
#if MMSQL
|
||||
|
||||
using MrWu.Model;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.Data.SqlClient;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MrWu.DB
|
||||
{
|
||||
/// <summary>
|
||||
/// sqlServer 操作
|
||||
/// </summary>
|
||||
public class MMSSQL : SqlEx<SqlConnection, SqlCommand, SqlDbType, SqlParameter>
|
||||
{
|
||||
#region 属性与字段
|
||||
|
||||
/// <summary>
|
||||
/// 链接池
|
||||
/// </summary>
|
||||
public override IConnectionPool<SqlConnection> connPool
|
||||
{
|
||||
get => null; // _ConnPool;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string connectionString { get; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region CTOR
|
||||
|
||||
/// <summary>
|
||||
/// 初始化
|
||||
/// </summary>
|
||||
/// <param name="config"></param>
|
||||
public MMSSQL(SqlConfig config)
|
||||
{
|
||||
//this._ConnPool = new ConnectionPool(config);
|
||||
this.connectionString =
|
||||
string.Format("Data Source={0},{1};user id={2};pwd={3};Max Pool Size=512;initial catalog=", config.host,
|
||||
config.port, config.username, config.pwd);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region SQL存储过程
|
||||
|
||||
/// <summary>
|
||||
/// 开始存储过程
|
||||
/// </summary>
|
||||
/// <param name="dbbase">存储过程所在的数据库</param>
|
||||
/// <param name="procedure">存储过程名</param>
|
||||
/// <returns></returns>
|
||||
public override IProdureParameter<SqlCommand> BeginProcedure(string dbbase, string procedure)
|
||||
{
|
||||
//if (_ConnPool == null)
|
||||
// throw new Exception("you dont hava init");
|
||||
|
||||
SqlCommand cmd = new SqlCommand(procedure); //, GetConnection(dbbase)
|
||||
SqlProcedureParameter result = new SqlProcedureParameter(cmd, dbbase);
|
||||
//存储过程模式
|
||||
cmd.CommandType = System.Data.CommandType.StoredProcedure;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 添加参数
|
||||
/// </summary>
|
||||
/// <param name="spp">存储过程查询键</param>
|
||||
/// <param name="paramName">参数名</param>
|
||||
/// <param name="value">参数值</param>
|
||||
/// <param name="type">参数类型</param>
|
||||
/// <param name="pd">参数种类</param>
|
||||
public override void AddParam(IProdureParameter<SqlCommand> spp, string paramName, object value, SqlDbType type,
|
||||
ParameterDirection pd = ParameterDirection.Input)
|
||||
{
|
||||
if (spp == null || spp.command == null)
|
||||
throw new Exception("param spp null");
|
||||
SqlParameter param = spp.command.Parameters.Add(paramName, type);
|
||||
param.Direction = pd;
|
||||
if (value == null)
|
||||
param.Value = DBNull.Value;
|
||||
else
|
||||
param.Value = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 提交存储过程
|
||||
/// </summary>
|
||||
/// <param name="spp">存储过程查询键</param>
|
||||
/// <param name="ds">如果 存储过程中有查询表操作,则需要传递DataSet实例</param>
|
||||
/// <param name="againCount">重试次数 小于0表示使用配置值 大于等于0表示自定义</param>
|
||||
/// <returns>参数值,输出参数从字典中获取</returns>
|
||||
public override Dictionary<string, object> SubProcedure(IProdureParameter<SqlCommand> spp, DataSet ds = null,
|
||||
int againCount = -1)
|
||||
{
|
||||
if (spp == null || spp.command == null)
|
||||
throw new Exception("param spp null");
|
||||
|
||||
int cnt = Execute(spp.command, spp.dbName, ds, againCount);
|
||||
|
||||
Dictionary<string, object> dic = new Dictionary<string, object>();
|
||||
var pms = spp.command.Parameters;
|
||||
int len = pms.Count;
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
dic.Add(pms[i].ParameterName, pms[i].Value);
|
||||
}
|
||||
|
||||
if (!dic.ContainsKey(DbConst.RowsAffected))
|
||||
{
|
||||
dic[DbConst.RowsAffected] = cnt;
|
||||
}
|
||||
|
||||
spp.Dispose();
|
||||
return dic;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region SQL Query
|
||||
|
||||
/// <summary>
|
||||
/// 执行sql语句
|
||||
/// </summary>
|
||||
/// <param name="dbbase">数据库</param>
|
||||
/// <param name="sql">sql语句</param>
|
||||
/// <param name="sqlparams">单独设置sql语句的参数 一般用来设置二进制参数 或者过长的文字字符串</param>
|
||||
/// <param name="againCount">重试次数 小于0表示使用配置值 大于等于0表示自定义</param>
|
||||
/// <param name="ds">如果是查询 使用传入ds实例</param>
|
||||
public override int ExecuteSql(string dbbase, string sql, IEnumerable<SqlParameter> sqlparams = null,
|
||||
DataSet ds = null, int againCount = -1)
|
||||
{
|
||||
SqlCommand cmd = new SqlCommand(sql); //, GetConnection(dbbase)
|
||||
cmd.CommandType = CommandType.Text;
|
||||
|
||||
if (sqlparams != null)
|
||||
{
|
||||
//int len = sqlparams.Count();
|
||||
//for (int i = 0; i < len; i++) {
|
||||
// ISqlAloneParameter<SqlDbType> sap = sqlparams[i];
|
||||
// cmd.Parameters.Add(sap.paramname, sap.type, sap.valueLength);
|
||||
// cmd.Parameters[sap.paramname].Value = sap.paramvalue;
|
||||
//}
|
||||
foreach (var param in sqlparams)
|
||||
{
|
||||
cmd.Parameters.Add(param);
|
||||
}
|
||||
}
|
||||
|
||||
return Execute(cmd, dbbase, ds, againCount);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 普通查询一个表
|
||||
/// </summary>
|
||||
/// <param name="dbbase">数据库名称</param>
|
||||
/// <param name="table">表名</param>
|
||||
/// <param name="column">列名</param>
|
||||
/// <param name="where">条件</param>
|
||||
/// <param name="count">查询的数量</param>
|
||||
/// <param name="againCount">重试次数 小于0表示使用配置值 大于等于0表示自定义</param>
|
||||
/// <param name="sqlparams">sql参数</param>
|
||||
/// <returns>查询到的表</returns>
|
||||
public override DataTable Select(string dbbase, string table, string[] column = null, string where = null,
|
||||
int count = 0, int againCount = -1, IEnumerable<SqlParameter> sqlparams = null)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.Append("select ");
|
||||
if (count > 0)
|
||||
{
|
||||
sb.Append(string.Format("Top {0} ", count));
|
||||
}
|
||||
|
||||
if (column != null && column.Length > 0)
|
||||
{
|
||||
int len = column.Length;
|
||||
for (int i = len - 1; i >= 0; i--)
|
||||
{
|
||||
sb.Append(column[i]);
|
||||
if (i > 0)
|
||||
sb.Append(",");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sb.Append("*");
|
||||
}
|
||||
|
||||
sb.Append(" from ");
|
||||
sb.Append(table);
|
||||
if (!string.IsNullOrEmpty(where))
|
||||
{
|
||||
sb.Append(" where ");
|
||||
sb.Append(where);
|
||||
}
|
||||
|
||||
DataSet ds = new DataSet();
|
||||
|
||||
//Debug.Debug.Info("sql:" + sb.ToString());
|
||||
ExecuteSql(dbbase, sb.ToString(), sqlparams, ds, againCount);
|
||||
if (ds.Tables == null || ds.Tables.Count == 0)
|
||||
return null;
|
||||
return ds.Tables[0];
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region SQL 事务
|
||||
|
||||
/// <summary>
|
||||
/// 开始一个事务
|
||||
/// </summary>
|
||||
/// <param name="dbbase">数据库</param>
|
||||
/// <returns></returns>
|
||||
public override IProdureParameter<SqlCommand> BeginTransaction(string dbbase)
|
||||
{
|
||||
SqlCommand cmd = new SqlCommand();
|
||||
SqlProcedureParameter spp = new SqlProcedureParameter(cmd, dbbase);
|
||||
try
|
||||
{
|
||||
var conn = GetConnection(dbbase);
|
||||
{
|
||||
conn.Open();
|
||||
cmd.Connection = conn;
|
||||
cmd.Connection.ChangeDatabase(dbbase);
|
||||
cmd.Transaction = cmd.Connection.BeginTransaction(); //开始事务,还可以设置隔离等级
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
spp.exception = e;
|
||||
if (cmd.Connection != null)
|
||||
{
|
||||
cmd.Connection.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
return spp;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 事务添加sql语句
|
||||
/// </summary>
|
||||
/// <param name="spp"></param>
|
||||
/// <param name="sql"></param>
|
||||
/// <param name="sqlparams"></param>
|
||||
public override int TransactionAddSql(IProdureParameter<SqlCommand> spp, string sql,
|
||||
List<ISqlAloneParameter<SqlDbType>> sqlparams = null)
|
||||
{
|
||||
if (spp.isException)
|
||||
return 0;
|
||||
try
|
||||
{
|
||||
SqlCommand cmd = spp.command;
|
||||
cmd.CommandText = sql;
|
||||
|
||||
cmd.Parameters.Clear();
|
||||
if (sqlparams != null)
|
||||
{
|
||||
int len = sqlparams.Count;
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
ISqlAloneParameter<SqlDbType> sap = sqlparams[i];
|
||||
if (sap.valueLength > 0)
|
||||
cmd.Parameters.Add(sap.paramname, sap.type, sap.valueLength);
|
||||
else
|
||||
cmd.Parameters.Add(sap.paramname, sap.type);
|
||||
cmd.Parameters[sap.paramname].Value = sap.paramvalue;
|
||||
cmd.Parameters[sap.paramname].Direction = sap.Direction;
|
||||
}
|
||||
}
|
||||
|
||||
var result = cmd.ExecuteNonQuery();
|
||||
if (sqlparams != null)
|
||||
{
|
||||
for (int i = 0; i < sqlparams.Count; i++)
|
||||
{
|
||||
sqlparams[i].paramvalue = cmd.Parameters[i].Value;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
spp.command.Transaction.Rollback(); //事务步骤异常,主动回滚事务
|
||||
spp.exception = e;
|
||||
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 提交事务
|
||||
/// </summary>
|
||||
/// <param name="spp"></param>
|
||||
/// <returns>true 表示提交成功 false 表示提交失败</returns>
|
||||
public override bool SubTransaction(IProdureParameter<SqlCommand> spp)
|
||||
{
|
||||
using (spp)
|
||||
{
|
||||
using (spp.command)
|
||||
{
|
||||
using (spp.command.Connection)
|
||||
{
|
||||
using (spp.command.Transaction)
|
||||
{
|
||||
try
|
||||
{
|
||||
spp.command.Transaction.Commit();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
spp.exception = e;
|
||||
spp.command.Transaction.Rollback();
|
||||
}
|
||||
|
||||
return spp.exception == null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 回滚事务
|
||||
/// </summary>
|
||||
/// <param name="spp"></param>
|
||||
public override void RollbackTransaction(IProdureParameter<SqlCommand> spp)
|
||||
{
|
||||
try
|
||||
{
|
||||
spp.command.Transaction.Rollback(); //事务步骤异常,主动回滚事务
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine(ex);
|
||||
}
|
||||
|
||||
spp.command.Transaction?.Dispose();
|
||||
spp.command.Connection?.Dispose();
|
||||
spp.command.Dispose();
|
||||
spp.Dispose();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region 异步方法
|
||||
|
||||
/// <summary>
|
||||
/// 异步提交存储过程
|
||||
/// </summary>
|
||||
public override async Task<Dictionary<string, object>> SubProcedureAsync(IProdureParameter<SqlCommand> spp,
|
||||
DataSet ds = null, int againCount = -1)
|
||||
{
|
||||
if (spp == null || spp.command == null)
|
||||
throw new Exception("param spp null");
|
||||
|
||||
int cnt = await ExecuteAsync(spp.command, spp.dbName, ds, againCount);
|
||||
|
||||
Dictionary<string, object> dic = new Dictionary<string, object>();
|
||||
var pms = spp.command.Parameters;
|
||||
int len = pms.Count;
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
dic.Add(pms[i].ParameterName, pms[i].Value);
|
||||
}
|
||||
|
||||
if (!dic.ContainsKey(DbConst.RowsAffected))
|
||||
{
|
||||
dic[DbConst.RowsAffected] = cnt;
|
||||
}
|
||||
|
||||
spp.Dispose();
|
||||
return dic;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 异步执行sql语句
|
||||
/// </summary>
|
||||
public override async Task<int> ExecuteSqlAsync(string dbbase, string sql,
|
||||
IEnumerable<SqlParameter> sqlparams = null, DataSet ds = null, int againCount = -1)
|
||||
{
|
||||
SqlCommand cmd = new SqlCommand(sql);
|
||||
cmd.CommandType = CommandType.Text;
|
||||
|
||||
if (sqlparams != null)
|
||||
{
|
||||
foreach (var param in sqlparams)
|
||||
{
|
||||
cmd.Parameters.Add(param);
|
||||
}
|
||||
}
|
||||
|
||||
return await ExecuteAsync(cmd, dbbase, ds, againCount);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 异步查询
|
||||
/// </summary>
|
||||
public override async Task<DataTable> SelectAsync(string dbbase, string table, string[] column = null,
|
||||
string where = null, int count = 0, int againCount = -1, IEnumerable<SqlParameter> sqlparams = null)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.Append("select ");
|
||||
if (count > 0)
|
||||
{
|
||||
sb.Append(string.Format("Top {0} ", count));
|
||||
}
|
||||
|
||||
if (column != null && column.Length > 0)
|
||||
{
|
||||
int len = column.Length;
|
||||
for (int i = len - 1; i >= 0; i--)
|
||||
{
|
||||
sb.Append(column[i]);
|
||||
if (i > 0)
|
||||
sb.Append(",");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sb.Append("*");
|
||||
}
|
||||
|
||||
sb.Append(" from ");
|
||||
sb.Append(table);
|
||||
if (!string.IsNullOrEmpty(where))
|
||||
{
|
||||
sb.Append(" where ");
|
||||
sb.Append(where);
|
||||
}
|
||||
|
||||
DataSet ds = new DataSet();
|
||||
|
||||
await ExecuteSqlAsync(dbbase, sb.ToString(), sqlparams, ds, againCount);
|
||||
if (ds.Tables == null || ds.Tables.Count == 0)
|
||||
return null;
|
||||
return ds.Tables[0];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 异步执行cmd
|
||||
/// </summary>
|
||||
public override async Task<int> ExecuteAsync(SqlCommand cmd, string dbname, DataSet ds = null,
|
||||
int againCount = -1)
|
||||
{
|
||||
int result = 0;
|
||||
int exceCnt = 0;
|
||||
if (againCount < 0)
|
||||
againCount = errorTryAgainCount;
|
||||
|
||||
while (exceCnt <= againCount)
|
||||
{
|
||||
try
|
||||
{
|
||||
using (cmd)
|
||||
{
|
||||
using (var conn = GetConnection(dbname))
|
||||
{
|
||||
await conn.OpenAsync();
|
||||
cmd.Connection = conn;
|
||||
cmd.Connection.ChangeDatabase(dbname);
|
||||
if (ds == null)
|
||||
{
|
||||
result = await cmd.ExecuteNonQueryAsync();
|
||||
}
|
||||
else
|
||||
{
|
||||
using (var sda = new SqlDataAdapter())
|
||||
{
|
||||
sda.SelectCommand = cmd;
|
||||
sda.Fill(ds);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
if (exceCnt < againCount)
|
||||
{
|
||||
Debug.Debug.Warning("数据库异步执行错误重试次数:" + exceCnt + ",错误类型:" + e.Message);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
int time = errorAgainTime + errorAgainTimeInc * exceCnt;
|
||||
exceCnt++;
|
||||
await Task.Delay(time);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region SQL Common
|
||||
|
||||
/// <summary>
|
||||
/// 获取一个连接
|
||||
/// </summary>
|
||||
/// <param name="dbbase"></param>
|
||||
/// <returns></returns>
|
||||
public override SqlConnection GetConnection(string dbbase) => new SqlConnection(connectionString + dbbase);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 执行sql命令
|
||||
/// </summary>
|
||||
/// <param name="cmd"></param>
|
||||
/// <param name="dbname">数据库名称</param>
|
||||
/// <param name="ds"></param>
|
||||
/// <param name="againCount">重试次数 小于0表示使用配置值 大于等于0表示自定义</param>
|
||||
public override int Execute(SqlCommand cmd, string dbname, DataSet ds = null, int againCount = -1)
|
||||
{
|
||||
int result = 0;
|
||||
int exceCnt = 0;
|
||||
if (againCount < 0)
|
||||
againCount = errorTryAgainCount;
|
||||
|
||||
while (exceCnt <= againCount)
|
||||
{
|
||||
try
|
||||
{
|
||||
using (cmd)
|
||||
{
|
||||
// Debug.Debug.Info("链接字符串:" + connectionString);
|
||||
using (var conn = GetConnection(dbname))
|
||||
{
|
||||
conn.Open();
|
||||
cmd.Connection = conn;
|
||||
cmd.Connection.ChangeDatabase(dbname);
|
||||
if (ds == null)
|
||||
{
|
||||
result = cmd.ExecuteNonQuery();
|
||||
}
|
||||
else
|
||||
{
|
||||
using (var sda = new SqlDataAdapter())
|
||||
{
|
||||
//一定要关闭,不然下次执行报错;
|
||||
sda.SelectCommand = cmd;
|
||||
sda.Fill(ds); //调用会自动执行 ExecuteNonQuery(); 不要重复调用,很容易出错!
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
if (exceCnt < againCount)
|
||||
{
|
||||
Debug.Debug.Warning("数据库执行错误重试次数:" + exceCnt + ",错误类型:" + e.Message);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
int time = errorAgainTime + errorAgainTimeInc * exceCnt;
|
||||
exceCnt++; //执行次数+1
|
||||
Thread.Sleep(time);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user