using System;
using System.Data.Common;
using System.Data;
using System.Data.SqlClient;
using System.Configuration;
using System.Collections.Generic;
using Mall.DataAccess.Utils;

namespace Mall.DataAccess.SqlDBHelper
{
    /// <summary>
    /// 数据库访问适配器 默认连接字符串使用【DefaultConnection】
    /// </summary>
    public class DBAdaptor : IDBHelper
    {
        private readonly string _ConnectionStringKey = "DefaultConnection";

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="connectionStringKey">连接字符串Key</param>
        public DBAdaptor(string connectionStringKey = "")
        {
            if (!string.IsNullOrEmpty(connectionStringKey))
            {
                _ConnectionStringKey = connectionStringKey;
            }
        }

        /// <summary>
        /// 取得数据库连接
        /// </summary>
        /// <param name="connectionStringKey">连接字符串Key</param>
        /// <returns></returns>
        public static SqlConnection GetConnByKey(string connectionStringKey)
        {
            ConnectionStringSettings css = ConfigurationManager.ConnectionStrings[connectionStringKey];
            string constr = css.ConnectionString;
            SqlConnection con = new SqlConnection(constr);
            return con;
        }

        /// <summary>
        /// 生成分页SQL语句
        /// </summary>
        /// <param name="pageIndex">页码</param>
        /// <param name="pageSize">页大小</param>
        /// <param name="selectSql">sql语句</param>
        /// <param name="sqlCount">sql条数统计</param>
        /// <param name="orderBy">排序</param>
        /// <returns></returns>
        public string GetPagingSql(int pageIndex, int pageSize, string selectSql, string sqlCount, string orderBy)
        {
            return PageHelper.GetPagingSql(pageIndex, pageSize, selectSql, sqlCount, orderBy);
        }

        #region 事务
        /// <summary>
        /// 开始一个事务
        /// </summary>
        public IDbTransaction BeginTractionand(IsolationLevel Iso = IsolationLevel.Unspecified)
        {
            SqlConnection con = GetConnByKey(_ConnectionStringKey);
            IDbTransaction transaction = SQLHelper.BeginTransaction(con, Iso);
            return transaction;
        }

        /// <summary>
        /// 开始一个事务
        /// </summary>
        public IDbTransaction BeginTractionand(string connKey, IsolationLevel Iso = IsolationLevel.Unspecified)
        {
            SqlConnection con = GetConnByKey(connKey);
            IDbTransaction transaction = SQLHelper.BeginTransaction(con, Iso);
            return transaction;
        }

        /// <summary>
        /// 回滚事务
        /// </summary>
        public void RollbackTractionand(IDbTransaction dbTransaction)
        {
            SQLHelper.EndTransactionRollback(dbTransaction);
        }

        /// <summary>
        /// 结束并确认事务
        /// </summary>
        public void CommitTractionand(IDbTransaction dbTransaction)
        {
            SQLHelper.EndTransactionCommit(dbTransaction);
        }
        #endregion

        #region ExecuteDataSet
        /// <summary>
        /// 执行SQL语句或者存储过程 ,返回参数dataset
        /// </summary>
        /// <param name="commandText">SQL语句或者存储过程名</param>
        /// <param name="commandParameters">SQL语句或者存储过程参数</param>
        /// <param name="commandType">SQL语句类型</param>
        /// <param name="commandTimeout">超时时间</param>
        /// <returns>执行结果集</returns>
        public DataSet ExecuteDataSet(string commandText, List<IDataParameter> commandParameters = null, CommandType commandType = CommandType.Text, int? commandTimeout = null)
        {
            return ExecuteDataSet(_ConnectionStringKey, commandText, commandParameters, commandType, commandTimeout);
        }

        /// <summary>
        ///  执行SQL语句或者存储过程 ,返回参数dataset
        /// </summary>
        /// <param name="connKey">连接字符串Key</param>
        /// <param name="commandText">SQL语句或者存储过程名</param>
        /// <param name="commandParameters">SQL语句或者存储过程参数</param>
        /// <param name="commandType">SQL语句类型</param>
        /// <param name="commandTimeout">超时时间</param>
        /// <returns>执行结果集</returns>
        public DataSet ExecuteDataSet(string connKey, string commandText, List<IDataParameter> commandParameters = null, CommandType commandType = CommandType.Text, int? commandTimeout = null)
        {
            using (SqlConnection conn = GetConnByKey(connKey))
            {
                return SQLHelper.ExecuteDataset(conn, commandText, commandParameters, commandType, commandTimeout);
            }
        }

        /// <summary>
        /// 执行SQL语句或者存储过程 ,返回参数dataset
        /// </summary>
        /// <param name="conn">要执行SQL语句的连接</param>
        /// <param name="commandText">SQL语句或者存储过程名</param>
        /// <param name="commandParameters">SQL语句或者存储过程参数</param>
        /// <param name="commandType">SQL语句类型</param>
        /// <param name="commandTimeout">超时时间</param>
        /// <returns>执行结果集</returns>
        public DataSet ExecuteDataSet(IDbConnection conn, string commandText, List<IDataParameter> commandParameters = null, CommandType commandType = CommandType.Text, int? commandTimeout = null)
        {
            return SQLHelper.ExecuteDataset((SqlConnection)conn, commandText, commandParameters, commandType, commandTimeout);
        }

        /// <summary>
        /// 执行SQL语句或者存储过程 ,返回参数dataset
        /// </summary>
        /// <param name="trans">语句所在的事务</param>
        /// <param name="commandText">SQL语句或者存储过程名</param>
        /// <param name="commandParameters">SQL语句或者存储过程参数</param>
        /// <param name="commandType">SQL语句类型</param>
        /// <param name="commandTimeout">超时时间</param>
        /// <returns>执行结果集</returns>
        public DataSet ExecuteDataSet(IDbTransaction trans, string commandText, List<IDataParameter> commandParameters = null, CommandType commandType = CommandType.Text, int? commandTimeout = null)
        {
            return SQLHelper.ExecuteDataset(trans, commandText, commandParameters, commandType, commandTimeout);
        }

        #endregion

        #region ExecuteNonQuery
        /// <summary>
        /// 执行SQL语句或者存储过程 ,只返回影响行数
        /// </summary>
        /// <param name="commandText">SQL语句或者存储过程名</param>
        /// <param name="commandParameters">SQL语句或者存储过程参数</param>
        /// <param name="commandType">SQL语句类型</param>
        /// <param name="commandTimeout">超时时间</param>
        /// <returns>影响的行数</returns>
        public int ExecuteNonQuery(string commandText, List<IDataParameter> commandParameters = null, CommandType commandType = CommandType.Text, int? commandTimeout = null)
        {
            return ExecuteNonQuery(_ConnectionStringKey, commandText, commandParameters, commandType, commandTimeout);
        }

        /// <summary>
        /// 执行SQL语句或者存储过程 ,只返回影响行数
        /// </summary>
        /// <param name="connKey">连接字符串Key</param>
        /// <param name="commandText">SQL语句或者存储过程名</param>
        /// <param name="commandParameters">SQL语句或者存储过程参数</param>
        /// <param name="commandType">SQL语句类型</param>
        /// <param name="commandTimeout">超时时间</param>
        /// <returns>影响的行数</returns>
        public int ExecuteNonQuery(string connKey, string commandText, List<IDataParameter> commandParameters = null, CommandType commandType = CommandType.Text, int? commandTimeout = null)
        {
            using (SqlConnection conn = GetConnByKey(connKey))
            {
                return SQLHelper.ExecuteNonQuery(conn, commandText, commandParameters, commandType, commandTimeout);
            }
        }

        /// <summary>
        /// 执行SQL语句或者存储过程 ,只返回影响行数
        /// </summary>
        /// <param name="conn">要执行SQL语句的连接</param>
        /// <param name="commandText">SQL语句或者存储过程名</param>
        /// <param name="commandParameters">SQL语句或者存储过程参数</param>
        /// <param name="commandType">SQL语句类型</param>
        /// <param name="commandTimeout">超时时间</param>
        /// <returns>影响的行数</returns>
        public int ExecuteNonQuery(IDbConnection conn, string commandText, List<IDataParameter> commandParameters = null, CommandType commandType = CommandType.Text, int? commandTimeout = null)
        {
            return SQLHelper.ExecuteNonQuery((SqlConnection)conn, commandText, commandParameters, commandType, commandTimeout);
        }

        /// <summary>
        /// 执行SQL语句或者存储过程 ,只返回影响行数
        /// </summary>
        /// <param name="trans">语句所在的事务</param>
        /// <param name="commandText">SQL语句或者存储过程名</param>
        /// <param name="commandParameters">SQL语句或者存储过程参数</param>
        /// <param name="commandType">SQL语句类型</param>
        /// <param name="commandTimeout">超时时间</param>
        /// <returns>影响的行数</returns>
        public int ExecuteNonQuery(IDbTransaction trans, string commandText, List<IDataParameter> commandParameters = null, CommandType commandType = CommandType.Text, int? commandTimeout = null)
        {
            return SQLHelper.ExecuteNonQuery(trans, commandText, commandParameters, commandType, commandTimeout);
        }
        #endregion

        #region ExecuteReader

        /// <summary>
        /// 执行SQL语句或者存储过程 ,返回DataReader
        /// </summary>
        /// <param name="commandText">SQL语句或者存储过程名</param>
        /// <param name="commandParameters">SQL语句或者存储过程参数</param>
        /// <param name="commandType">SQL语句类型</param>
        /// <param name="commandTimeout">超时时间</param>
        /// <returns>DataReader</returns>
        public IDataReader ExecuteReader(string commandText, List<IDataParameter> commandParameters = null, CommandType commandType = CommandType.Text, int? commandTimeout = null)
        {
            return ExecuteReader(_ConnectionStringKey, commandText, commandParameters, commandType, commandTimeout);
        }

        /// <summary>
        /// 执行SQL语句或者存储过程 ,返回DataReader
        /// </summary>
        /// <param name="connKey">连接字符串Key</param>
        /// <param name="commandText">SQL语句或者存储过程名</param>
        /// <param name="commandParameters">SQL语句或者存储过程参数</param>
        /// <param name="commandType">SQL语句类型</param>
        /// <param name="commandTimeout">超时时间</param>
        /// <returns>DataReader</returns>
        public IDataReader ExecuteReader(string connKey, string commandText, List<IDataParameter> commandParameters = null, CommandType commandType = CommandType.Text, int? commandTimeout = null)
        {
            SqlConnection conn = GetConnByKey(connKey);
            return SQLHelper.ExecuteReader(conn, commandText, commandParameters, commandType, commandTimeout);
        }

        /// <summary>
        /// 执行SQL语句或者存储过程 ,返回DataReader
        /// </summary>
        /// <param name="conn">要执行SQL语句的连接</param>
        /// <param name="commandText">SQL语句或者存储过程名</param>
        /// <param name="commandParameters">SQL语句或者存储过程参数</param>
        /// <param name="commandType">SQL语句类型</param>
        /// <param name="commandTimeout">超时时间</param>
        /// <returns>DataReader</returns>
        public IDataReader ExecuteReader(IDbConnection conn, string commandText, List<IDataParameter> commandParameters = null, CommandType commandType = CommandType.Text, int? commandTimeout = null)
        {
            return SQLHelper.ExecuteReader((SqlConnection)conn, commandText, commandParameters, commandType, commandTimeout);
        }

        /// <summary>
        /// 执行SQL语句或者存储过程 ,返回DataReader
        /// </summary>
        /// <param name="trans">语句所在的事务</param>
        /// <param name="commandText">SQL语句或者存储过程名</param>
        /// <param name="commandParameters">SQL语句或者存储过程参数</param>
        /// <param name="commandType">SQL语句类型</param>
        /// <param name="commandTimeout">超时时间</param>
        /// <returns>DataReader</returns>
        public IDataReader ExecuteReader(IDbTransaction trans, string commandText, List<IDataParameter> commandParameters = null, CommandType commandType = CommandType.Text, int? commandTimeout = null)
        {
            return SQLHelper.ExecuteReader(trans, commandText, commandParameters, commandType, commandTimeout);
        }
        #endregion

        #region ExecuteIEnumerable

        /// <summary>
        /// 执行SQL语句或者存储过程 ,返回IEnumerable
        /// </summary>
        /// <typeparam name="T">返回类似</typeparam>
        /// <param name="commandText">SQL语句或者存储过程名</param>
        /// <param name="commandParameters">SQL语句或者存储过程参数</param>
        /// <param name="commandType">SQL语句类型</param>
        /// <param name="commandTimeout">超时时间</param>
        /// <returns>IEnumerable</returns>
        public IEnumerable<T> ExecuteIEnumerable<T>(string commandText, List<IDataParameter> commandParameters = null, CommandType commandType = CommandType.Text, int? commandTimeout = null) where T : class, new()
        {
            return ExecuteIEnumerable<T>(_ConnectionStringKey, commandText, commandParameters, commandType, commandTimeout);
        }

        /// <summary>
        /// 执行SQL语句或者存储过程 ,返回IEnumerable
        /// </summary>
        /// <typeparam name="T">返回类似</typeparam>
        /// <param name="connKey">连接字符串Key</param>
        /// <param name="commandText">SQL语句或者存储过程名</param>
        /// <param name="commandParameters">SQL语句或者存储过程参数</param>
        /// <param name="commandType">SQL语句类型</param>
        /// <param name="commandTimeout">超时时间</param>
        /// <returns>IEnumerable</returns>
        public IEnumerable<T> ExecuteIEnumerable<T>(string connKey, string commandText, List<IDataParameter> commandParameters = null, CommandType commandType = CommandType.Text, int? commandTimeout = null) where T : class, new()
        {
            using (SqlConnection conn = GetConnByKey(connKey))
            {
                using (IDataReader dr = SQLHelper.ExecuteReader(conn, commandText, commandParameters, commandType, commandTimeout))
                {
                    return Utils.DataReaderExtensions.DataReaderToList<T>(dr);
                }
            }
        }


        /// <summary>
        /// 执行SQL语句或者存储过程 ,返回IEnumerable
        /// </summary>
        /// <typeparam name="T">返回类似</typeparam>
        /// <param name="conn">要执行SQL语句的连接</param>
        /// <param name="commandText">SQL语句或者存储过程名</param>
        /// <param name="commandParameters">SQL语句或者存储过程参数</param>
        /// <param name="commandType">SQL语句类型</param>
        /// <param name="commandTimeout">超时时间</param>
        /// <returns>IEnumerable</returns>
        public IEnumerable<T> ExecuteIEnumerable<T>(IDbConnection conn, string commandText, List<IDataParameter> commandParameters = null, CommandType commandType = CommandType.Text, int? commandTimeout = null) where T : class, new()
        {
            IDataReader dr = SQLHelper.ExecuteReader((SqlConnection)conn, commandText, commandParameters, commandType, commandTimeout);
            return Utils.DataReaderExtensions.DataReaderToList<T>(dr);
        }

        /// <summary>
        /// 执行SQL语句或者存储过程 ,返回IEnumerable
        /// </summary>
        /// <typeparam name="T">返回类似</typeparam>
        /// <param name="trans">语句所在的事务</param>
        /// <param name="commandText">SQL语句或者存储过程名</param>
        /// <param name="commandParameters">SQL语句或者存储过程参数</param>
        /// <param name="commandType">SQL语句类型</param>
        /// <param name="commandTimeout">超时时间</param>
        /// <returns>IEnumerable</returns>
        public IEnumerable<T> ExecuteIEnumerable<T>(IDbTransaction trans, string commandText, List<IDataParameter> commandParameters = null, CommandType commandType = CommandType.Text, int? commandTimeout = null) where T : class, new()
        {
            IDataReader dr = SQLHelper.ExecuteReader(trans, commandText, commandParameters, commandType, commandTimeout);
            return Utils.DataReaderExtensions.DataReaderToList<T>(dr);
        }
        #endregion

        #region ExecuteScalar
        /// <summary>
        /// 执行SQL语句或者存储过程 ,返回参数object．第一行，第一列的值
        /// </summary>
        /// <param name="commandText">SQL语句或者存储过程名</param>
        /// <param name="commandParameters">SQL语句或者存储过程参数</param>
        /// <param name="commandType">SQL语句类型</param>
        /// <param name="commandTimeout">超时时间</param>
        /// <returns>执行结果集第一行，第一列的值</returns>　
        public object ExecuteScalar(string commandText, List<IDataParameter> commandParameters = null, CommandType commandType = CommandType.Text, int? commandTimeout = null)
        {
            return ExecuteScalar(_ConnectionStringKey, commandText, commandParameters, commandType, commandTimeout);
        }


        /// <summary>
        /// 执行SQL语句或者存储过程 ,返回参数类似T．第一行，第一列的值
        /// </summary>
        /// <typeparam name="T">返回类型</typeparam>
        /// <param name="commandText">SQL语句或者存储过程名</param>
        /// <param name="commandParameters">SQL语句或者存储过程参数</param>
        /// <param name="commandType">SQL语句类型</param>
        /// <param name="commandTimeout">超时时间</param>
        /// <returns>执行结果集第一行，第一列的值</returns>　
        public T ExecuteScalar<T>(string commandText, List<IDataParameter> commandParameters = null, CommandType commandType = CommandType.Text, int? commandTimeout = null)
        {
            return (T)ExecuteScalar(_ConnectionStringKey, commandText, commandParameters, commandType, commandTimeout);
        }

        /// <summary>
        /// 执行SQL语句或者存储过程 ,返回参数object．第一行，第一列的值
        /// </summary>
        /// <param name="connKey">连接字符串Key</param>
        /// <param name="commandText">SQL语句或者存储过程名</param>
        /// <param name="commandParameters">SQL语句或者存储过程参数</param>
        /// <param name="commandType">SQL语句类型</param>
        /// <param name="commandTimeout">超时时间</param>
        /// <returns>执行结果集第一行，第一列的值</returns>　
        public object ExecuteScalar(string connKey, string commandText, List<IDataParameter> commandParameters = null, CommandType commandType = CommandType.Text, int? commandTimeout = null)
        {
            using (SqlConnection conn = GetConnByKey(connKey))
            {
                return SQLHelper.ExecuteScalar(conn, commandText, commandParameters, commandType, commandTimeout);
            }
        }

        /// <summary>
        /// 执行SQL语句或者存储过程 ,返回参数类似T．第一行，第一列的值
        /// </summary>
        /// <typeparam name="T">返回类型</typeparam>
        /// <param name="connKey">连接字符串Key</param>
        /// <param name="commandText">SQL语句或者存储过程名</param>
        /// <param name="commandParameters">SQL语句或者存储过程参数</param>
        /// <param name="commandType">SQL语句类型</param>
        /// <param name="commandTimeout">超时时间</param>
        /// <returns>执行结果集第一行，第一列的值</returns>　
        public T ExecuteScalar<T>(string connKey, string commandText, List<IDataParameter> commandParameters = null, CommandType commandType = CommandType.Text, int? commandTimeout = null)
        {
            return (T)ExecuteScalar(connKey, commandText, commandParameters, commandType, commandTimeout);
        }

        /// <summary>
        /// 执行SQL语句或者存储过程 ,返回参数object．第一行，第一列的值
        /// </summary>
        /// <param name="conn">要执行SQL语句的连接</param>
        /// <param name="commandText">SQL语句或者存储过程名</param>
        /// <param name="commandParameters">SQL语句或者存储过程参数</param>
        /// <param name="commandType">SQL语句类型</param>
        /// <param name="commandTimeout">超时时间</param>
        /// <returns>执行结果集第一行，第一列的值</returns>　
        public object ExecuteScalar(IDbConnection conn, string commandText, List<IDataParameter> commandParameters = null, CommandType commandType = CommandType.Text, int? commandTimeout = null)
        {
            return SQLHelper.ExecuteScalar((SqlConnection)conn, commandText, commandParameters, commandType, commandTimeout);
        }

        /// <summary>
        /// 执行SQL语句或者存储过程 ,返回参数类似T．第一行，第一列的值
        /// </summary>
        /// <typeparam name="T">返回类型</typeparam>
        /// <param name="conn">要执行SQL语句的连接</param>
        /// <param name="commandText">SQL语句或者存储过程名</param>
        /// <param name="commandParameters">SQL语句或者存储过程参数</param>
        /// <param name="commandType">SQL语句类型</param>
        /// <param name="commandTimeout">超时时间</param>
        /// <returns>执行结果集第一行，第一列的值</returns>　
        public T ExecuteScalar<T>(IDbConnection conn, string commandText, List<IDataParameter> commandParameters = null, CommandType commandType = CommandType.Text, int? commandTimeout = null)
        {
            return (T)ExecuteScalar(conn, commandText, commandParameters, commandType, commandTimeout);
        }


        /// <summary>
        /// 执行SQL语句或者存储过程 ,返回参数object．第一行，第一列的值
        /// </summary>
        /// <param name="trans">语句所在的事务</param>
        /// <param name="commandText">SQL语句或者存储过程名</param>
        /// <param name="commandParameters">SQL语句或者存储过程参数</param>
        /// <param name="commandType">SQL语句类型</param>
        /// <param name="commandTimeout">超时时间</param>
        /// <returns>执行结果集第一行，第一列的值</returns>　
        public object ExecuteScalar(IDbTransaction trans, string commandText, List<IDataParameter> commandParameters = null, CommandType commandType = CommandType.Text, int? commandTimeout = null)
        {
            return SQLHelper.ExecuteScalar(trans, commandText, commandParameters, commandType, commandTimeout);
        }

        /// <summary>
        /// 执行SQL语句或者存储过程 ,返回参数类似T．第一行，第一列的值
        /// </summary>
        /// <typeparam name="T">返回类型</typeparam>
        /// <param name="trans">语句所在的事务</param>
        /// <param name="commandText">SQL语句或者存储过程名</param>
        /// <param name="commandParameters">SQL语句或者存储过程参数</param>
        /// <param name="commandType">SQL语句类型</param>
        /// <param name="commandTimeout">超时时间</param>
        /// <returns>执行结果集第一行，第一列的值</returns>　
        public T ExecuteScalar<T>(IDbTransaction trans, string commandText, List<IDataParameter> commandParameters = null, CommandType commandType = CommandType.Text, int? commandTimeout = null)
        {
            return (T)ExecuteScalar(trans, commandText, commandParameters, commandType, commandTimeout);
        }
        #endregion
    }

}