using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
using System.Data.SqlClient;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
namespace SqlSugar
{
///
/// ** description:ActiveX Data Objects
/// ** author:sunkaixuan
/// ** date:2017/1/2
/// ** email:610262374@qq.com
///
public abstract partial class AdoProvider : AdoAccessory, IAdo
{
#region Constructor
public AdoProvider()
{
this.IsEnableLogEvent = false;
this.CommandType = CommandType.Text;
this.IsClearParameters = true;
this.CommandTimeOut = 300;
}
#endregion
#region Properties
protected List OutputParameters { get; set; }
public virtual string SqlParameterKeyWord { get { return "@"; } }
public IDbTransaction Transaction { get; set; }
public virtual SqlSugarProvider Context { get; set; }
internal CommandType OldCommandType { get; set; }
internal bool OldClearParameters { get; set; }
public IDataParameterCollection DataReaderParameters { get; set; }
public TimeSpan SqlExecutionTime { get { return AfterTime - BeforeTime; } }
public bool IsDisableMasterSlaveSeparation { get; set; }
internal DateTime BeforeTime = DateTime.MinValue;
internal DateTime AfterTime = DateTime.MinValue;
public virtual IDbBind DbBind
{
get
{
if (base._DbBind == null)
{
IDbBind bind = InstanceFactory.GetDbBind(this.Context.CurrentConnectionConfig);
base._DbBind = bind;
bind.Context = this.Context;
}
return base._DbBind;
}
}
public virtual int CommandTimeOut { get; set; }
public virtual CommandType CommandType { get; set; }
public virtual bool IsEnableLogEvent { get; set; }
public virtual bool IsClearParameters { get; set; }
public virtual Action LogEventStarting => this.Context.CurrentConnectionConfig.AopEvents?.OnLogExecuting;
public virtual Action LogEventCompleted => this.Context.CurrentConnectionConfig.AopEvents?.OnLogExecuted;
public virtual Func> ProcessingEventStartingSQL => this.Context.CurrentConnectionConfig.AopEvents?.OnExecutingChangeSql;
protected virtual Func FormatSql { get; set; }
public virtual Action ErrorEvent => this.Context.CurrentConnectionConfig.AopEvents?.OnError;
public virtual Action DiffLogEvent => this.Context.CurrentConnectionConfig.AopEvents?.OnDiffLogEvent;
public virtual List SlaveConnections { get; set; }
public virtual IDbConnection MasterConnection { get; set; }
#endregion
#region Connection
public virtual void Open()
{
CheckConnection();
}
public virtual void Close()
{
if (this.Transaction != null)
{
this.Transaction = null;
}
if (this.Connection != null && this.Connection.State == ConnectionState.Open)
{
this.Connection.Close();
}
if (this.IsMasterSlaveSeparation && this.SlaveConnections.HasValue())
{
foreach (var slaveConnection in this.SlaveConnections)
{
if (slaveConnection != null && slaveConnection.State == ConnectionState.Open)
{
slaveConnection.Close();
}
}
}
}
public virtual void Dispose()
{
if (this.Transaction != null)
{
this.Transaction.Commit();
this.Transaction = null;
}
if (this.Connection != null && this.Connection.State != ConnectionState.Open)
{
this.Connection.Close();
}
if (this.Connection != null)
{
this.Connection.Dispose();
}
this.Connection = null;
if (this.IsMasterSlaveSeparation)
{
if (this.SlaveConnections != null)
{
foreach (var slaveConnection in this.SlaveConnections)
{
if (slaveConnection != null && slaveConnection.State == ConnectionState.Open)
{
slaveConnection.Dispose();
}
}
}
}
}
public virtual void CheckConnection()
{
if (this.Connection.State != ConnectionState.Open)
{
try
{
this.Connection.Open();
}
catch (Exception ex)
{
Check.Exception(true, ErrorMessage.ConnnectionOpen, ex.Message);
}
}
}
#endregion
#region Transaction
public virtual void BeginTran()
{
CheckConnection();
if (this.Transaction == null)
this.Transaction = this.Connection.BeginTransaction();
}
public virtual void BeginTran(IsolationLevel iso)
{
CheckConnection();
if (this.Transaction == null)
this.Transaction = this.Connection.BeginTransaction(iso);
}
public virtual void RollbackTran()
{
if (this.Transaction != null)
{
this.Transaction.Rollback();
this.Transaction = null;
if (this.Context.CurrentConnectionConfig.IsAutoCloseConnection) this.Close();
}
}
public virtual void CommitTran()
{
if (this.Transaction != null)
{
this.Transaction.Commit();
this.Transaction = null;
if (this.Context.CurrentConnectionConfig.IsAutoCloseConnection) this.Close();
}
}
#endregion
#region abstract
public abstract IDataParameter[] ToIDbDataParameter(params SugarParameter[] pars);
public abstract void SetCommandToAdapter(IDataAdapter adapter, DbCommand command);
public abstract IDataAdapter GetAdapter();
public abstract DbCommand GetCommand(string sql, SugarParameter[] pars);
public abstract IDbConnection Connection { get; set; }
public abstract void BeginTran(string transactionName);//Only SqlServer
public abstract void BeginTran(IsolationLevel iso, string transactionName);//Only SqlServer
#endregion
#region Use
public DbResult UseTran(Action action, Action errorCallBack = null)
{
var result = new DbResult();
try
{
this.BeginTran();
if (action != null)
action();
this.CommitTran();
result.Data = result.IsSuccess = true;
}
catch (Exception ex)
{
result.ErrorException = ex;
result.ErrorMessage = ex.Message;
result.IsSuccess = false;
this.RollbackTran();
if (errorCallBack != null)
{
errorCallBack(ex);
}
}
return result;
}
public Task> UseTranAsync(Action action, Action errorCallBack = null)
{
return Task.FromResult(UseTran(action, errorCallBack));
}
public DbResult UseTran(Func action, Action errorCallBack = null)
{
var result = new DbResult();
try
{
this.BeginTran();
if (action != null)
result.Data = action();
this.CommitTran();
result.IsSuccess = true;
}
catch (Exception ex)
{
result.ErrorException = ex;
result.ErrorMessage = ex.Message;
result.IsSuccess = false;
this.RollbackTran();
if (errorCallBack != null)
{
errorCallBack(ex);
}
}
return result;
}
public Task> UseTranAsync(Func action, Action errorCallBack = null)
{
return Task.FromResult(UseTran(action, errorCallBack));
}
public IAdo UseStoredProcedure()
{
this.OldCommandType = this.CommandType;
this.OldClearParameters = this.IsClearParameters;
this.CommandType = CommandType.StoredProcedure;
this.IsClearParameters = false;
return this;
}
#endregion
#region Core
public virtual int ExecuteCommand(string sql, params SugarParameter[] parameters)
{
try
{
InitParameters(ref sql, parameters);
if (FormatSql != null)
sql = FormatSql(sql);
SetConnectionStart(sql);
if (this.ProcessingEventStartingSQL != null)
ExecuteProcessingSQL(ref sql, parameters);
ExecuteBefore(sql, parameters);
IDbCommand sqlCommand = GetCommand(sql, parameters);
int count = sqlCommand.ExecuteNonQuery();
if (this.IsClearParameters)
sqlCommand.Parameters.Clear();
ExecuteAfter(sql, parameters);
return count;
}
catch (Exception ex)
{
CommandType = CommandType.Text;
if (ErrorEvent != null)
ExecuteErrorEvent(sql, parameters, ex);
throw ex;
}
finally
{
if (this.IsAutoClose()) this.Close();
SetConnectionEnd(sql);
}
}
public virtual IDataReader GetDataReader(string sql, params SugarParameter[] parameters)
{
try
{
InitParameters(ref sql, parameters);
if (FormatSql != null)
sql = FormatSql(sql);
SetConnectionStart(sql);
var isSp = this.CommandType == CommandType.StoredProcedure;
if (this.ProcessingEventStartingSQL != null)
ExecuteProcessingSQL(ref sql, parameters);
ExecuteBefore(sql, parameters);
IDbCommand sqlCommand = GetCommand(sql, parameters);
IDataReader sqlDataReader = sqlCommand.ExecuteReader(this.IsAutoClose() ? CommandBehavior.CloseConnection : CommandBehavior.Default);
if (isSp)
DataReaderParameters = sqlCommand.Parameters;
if (this.IsClearParameters)
sqlCommand.Parameters.Clear();
ExecuteAfter(sql, parameters);
SetConnectionEnd(sql);
return sqlDataReader;
}
catch (Exception ex)
{
CommandType = CommandType.Text;
if (ErrorEvent != null)
ExecuteErrorEvent(sql, parameters, ex);
throw ex;
}
}
public virtual DataSet GetDataSetAll(string sql, params SugarParameter[] parameters)
{
try
{
InitParameters(ref sql, parameters);
if (FormatSql != null)
sql = FormatSql(sql);
SetConnectionStart(sql);
if (this.ProcessingEventStartingSQL != null)
ExecuteProcessingSQL(ref sql, parameters);
ExecuteBefore(sql, parameters);
IDataAdapter dataAdapter = this.GetAdapter();
DbCommand sqlCommand = GetCommand(sql, parameters);
this.SetCommandToAdapter(dataAdapter, sqlCommand);
DataSet ds = new DataSet();
dataAdapter.Fill(ds);
if (this.IsClearParameters)
sqlCommand.Parameters.Clear();
ExecuteAfter(sql, parameters);
return ds;
}
catch (Exception ex)
{
CommandType = CommandType.Text;
if (ErrorEvent != null)
ExecuteErrorEvent(sql, parameters, ex);
throw ex;
}
finally
{
if (this.IsAutoClose()) this.Close();
SetConnectionEnd(sql);
}
}
public virtual object GetScalar(string sql, params SugarParameter[] parameters)
{
try
{
InitParameters(ref sql, parameters);
if (FormatSql != null)
sql = FormatSql(sql);
SetConnectionStart(sql);
if (this.ProcessingEventStartingSQL != null)
ExecuteProcessingSQL(ref sql, parameters);
ExecuteBefore(sql, parameters);
IDbCommand sqlCommand = GetCommand(sql, parameters);
object scalar = sqlCommand.ExecuteScalar();
//scalar = (scalar == null ? 0 : scalar);
if (this.IsClearParameters)
sqlCommand.Parameters.Clear();
ExecuteAfter(sql, parameters);
return scalar;
}
catch (Exception ex)
{
CommandType = CommandType.Text;
if (ErrorEvent != null)
ExecuteErrorEvent(sql, parameters, ex);
throw ex;
}
finally
{
if (this.IsAutoClose()) this.Close();
SetConnectionEnd(sql);
}
}
public virtual async Task ExecuteCommandAsync(string sql, params SugarParameter[] parameters)
{
try
{
Async();
InitParameters(ref sql, parameters);
if (FormatSql != null)
sql = FormatSql(sql);
SetConnectionStart(sql);
if (this.ProcessingEventStartingSQL != null)
ExecuteProcessingSQL(ref sql, parameters);
ExecuteBefore(sql, parameters);
var sqlCommand = GetCommand(sql, parameters);
int count = await sqlCommand.ExecuteNonQueryAsync();
if (this.IsClearParameters)
sqlCommand.Parameters.Clear();
ExecuteAfter(sql, parameters);
return count;
}
catch (Exception ex)
{
CommandType = CommandType.Text;
if (ErrorEvent != null)
ExecuteErrorEvent(sql, parameters, ex);
throw ex;
}
finally
{
if (this.IsAutoClose()) this.Close();
SetConnectionEnd(sql);
}
}
public virtual async Task GetDataReaderAsync(string sql, params SugarParameter[] parameters)
{
try
{
Async();
InitParameters(ref sql, parameters);
if (FormatSql != null)
sql = FormatSql(sql);
SetConnectionStart(sql);
var isSp = this.CommandType == CommandType.StoredProcedure;
if (this.ProcessingEventStartingSQL != null)
ExecuteProcessingSQL(ref sql, parameters);
ExecuteBefore(sql, parameters);
var sqlCommand = GetCommand(sql, parameters);
var sqlDataReader = await sqlCommand.ExecuteReaderAsync(this.IsAutoClose() ? CommandBehavior.CloseConnection : CommandBehavior.Default);
if (isSp)
DataReaderParameters = sqlCommand.Parameters;
if (this.IsClearParameters)
sqlCommand.Parameters.Clear();
ExecuteAfter(sql, parameters);
SetConnectionEnd(sql);
return sqlDataReader;
}
catch (Exception ex)
{
CommandType = CommandType.Text;
if (ErrorEvent != null)
ExecuteErrorEvent(sql, parameters, ex);
throw ex;
}
}
public virtual async Task