using System;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using System.Threading.Tasks;
namespace DS.JZB.Common {
public abstract class DbConnectionManipulator {
public static string DatabaseConnectionStringName = "DatabaseCs";
public static string IndexDatabaseConnectionStringName = "DatabaseCs";
public const int SplitDatabaseCount = 8;
protected IDbConnection GetConnection() {
return GetMainDatabaseConnection();
}
protected void Run(Action<IDbConnection> work) {
Run(GetConnection(), work);
}
protected void Run(IDbConnection connection, Action<IDbConnection> work) {
using (connection) {
work(connection);
}
}
protected void RunInTransaction(Action<IDbConnection, IDbTransaction> work) {
RunInTransaction(GetConnection(), work);
}
protected void RunInTransaction(IDbConnection connection, Action<IDbConnection, IDbTransaction> work) {
using (connection) {
using (var transaction = connection.BeginTransaction()) {
try {
work(connection, transaction);
transaction.Commit();
}
catch {
transaction.Rollback();
throw;
}
}
}
}
public static IDbConnection GetMainDatabaseConnection(string databaseCs = "") {
//if (string.IsNullOrEmpty(databaseCs)) {
// if (UserContext.CurrentUser != null && UserContext.CurrentUser.GlobalTeamId > 0) {
// var teamId = UserContext.CurrentUser.GlobalTeamId;
// DatabaseConnectionStringName = "DatabaseCs" + (teamId % SplitDatabaseCount + 1);
// }
// else {
// DatabaseConnectionStringName = "DatabaseCs";
// }
//}
//else {
// DatabaseConnectionStringName = databaseCs;
//}
var connection =
new SqlConnection(ConfigurationManager.ConnectionStrings[DatabaseConnectionStringName].ConnectionString);
connection.EnsureOpen();
return connection;
}
public static void RunMainDatabase(Action<IDbConnection> work, string databaseCs = "") {
RunMainDatabase(GetMainDatabaseConnection(databaseCs), work);
}
public static T RunMainDatabase<T>(Func<IDbConnection, T> work, string databaseCs = "") {
return RunMainDatabase(GetMainDatabaseConnection(databaseCs), work);
}
private static void RunMainDatabase(IDbConnection connection, Action<IDbConnection> work) {
using (connection) {
work(connection);
}
}
private static T RunMainDatabase<T>(IDbConnection connection, Func<IDbConnection, T> work) {
using (connection) {
return work(connection);
}
}
public static void RunMainDatabaseInTransaction(Action<IDbConnection, IDbTransaction> work,
string databaseCs = "") {
RunMainDatabaseInTransaction(GetMainDatabaseConnection(databaseCs), work);
}
public static T RunMainDatabaseInTransaction<T>(Func<IDbConnection, IDbTransaction, T> work,
string databaseCs = "") {
return RunMainDatabaseInTransaction(GetMainDatabaseConnection(databaseCs), work);
}
public static void RunMainDatabaseInTransaction(IDbConnection connection,
Action<IDbConnection, IDbTransaction> work) {
#if DEBUG
//var guid = Guid.Empty;
//if (HttpContext.Current.Items.Contains("DUUID")) {
// guid = (Guid)HttpContext.Current.Items["DUUID"];
//}
//else {
// guid = Guid.NewGuid();
// HttpContext.Current.Items["DUUID"] = guid;
//}
//var logger = typeof(DbConnectionManipulator).ObtainLog();
//logger.Debug($"[{guid.ToString("n")}] get connection to execute db queries");
#endif
using (connection) {
using (var transaction = connection.BeginTransaction()) {
try {
work(connection, transaction);
transaction.Commit();
}
catch(Exception ex) {
transaction.Rollback();
throw;
}
}
}
#if DEBUG
//logger.Debug($"[{guid.ToString("n")}] release connection to connection pool");
#endif
}
public static T RunMainDatabaseInTransaction<T>(IDbConnection connection,
Func<IDbConnection, IDbTransaction, T> work) {
#if DEBUG
//var guid = Guid.Empty;
//if (HttpContext.Current.Items.Contains("DUUID")) {
// guid = (Guid)HttpContext.Current.Items["DUUID"];
//}
//else {
// guid = Guid.NewGuid();
// HttpContext.Current.Items["DUUID"] = guid;
//}
//var logger = typeof(DbConnectionManipulator).ObtainLog();
//logger.Debug($"[{guid.ToString("n")}] get connection to execute db queries");
#endif
T result = default(T);
using (connection) {
using (var transaction = connection.BeginTransaction()) {
try {
result = work(connection, transaction);
transaction.Commit();
}
catch {
transaction.Rollback();
throw;
}
}
}
#if DEBUG
//logger.Debug($"[{guid.ToString("n")}] release connection to connection pool");
#endif
return result;
}
public static void RunAllSplitDatabase(Action<IDbConnection> work) {
for (var i = 1; i <= SplitDatabaseCount; i++) {
RunMainDatabase(work, $"DatabaseCs{i}");
}
}
public static void ForEachSplitDatabase(Func<IDbConnection, bool> work) {
for (var i = 1; i <= SplitDatabaseCount; i++) {
if (RunMainDatabase(work, $"DatabaseCs{i}")) {
break;
}
}
}
public static int GetTeamDatabaseIndex(int teamId) {
return teamId % SplitDatabaseCount + 1;
}
public static string GetTeamDatabaseName(int teamId) {
return $"DatabaseCs{(teamId % SplitDatabaseCount + 1)}";
}
public static string GetIndexDatabaseName() {
return "DatabaseCs";
}
protected Task RunAsync(Func<IDbConnection, Task> work) {
return RunAsync(GetConnection(), work);
}
protected Task RunAsync(IDbConnection connection, Func<IDbConnection, Task> work) {
#if DEBUG
//var guid = Guid.Empty;
//if (HttpContext.Current.Items.Contains("DUUID")) {
// guid = (Guid)HttpContext.Current.Items["DUUID"];
//}
//else {
// guid = Guid.NewGuid();
// HttpContext.Current.Items["DUUID"] = guid;
//}
//var logger = typeof(DbConnectionManipulator).ObtainLog();
//logger.Debug($"[{guid.ToString("n")}] get connection to execute db queries");
#endif
Task result = null;
using (connection) {
result = work(connection);
connection.Dispose();
}
#if DEBUG
//logger.Debug($"[{guid.ToString("n")}] release connection to connection pool");
#endif
return result;
}
public static Task RunMainDatabaseAsync(Func<IDbConnection, Task> work) {
return RunMainDatabaseAsync(GetMainDatabaseConnection(), work);
}
private static async Task RunMainDatabaseAsync(IDbConnection connection, Func<IDbConnection, Task> work) {
#if DEBUG
//var guid = Guid.Empty;
//if (HttpContext.Current.Items.Contains("DUUID")) {
// guid = (Guid) HttpContext.Current.Items["DUUID"];
//}
//else {
// guid = Guid.NewGuid();
// HttpContext.Current.Items["DUUID"] = guid;
//}
//var logger = typeof(DbConnectionManipulator).ObtainLog();
//logger.Debug($"[{guid.ToString("n")}] get connection to execute db queries");
#endif
using (connection) {
await work(connection);
connection.Dispose();
}
#if DEBUG
//logger.Debug($"[{guid.ToString("n")}] release connection to connection pool");
#endif
}
}
public static class DbConnectionExtension {
public static void EnsureOpen(this IDbConnection @this) {
if (@this.State == ConnectionState.Closed) {
@this.Open();
}
}
}
}