using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Diagnostics;
using System.Reflection;
using System.Threading;
using System.Windows.Forms;
namespace HelperDB
{
    public static class DBHelper
    {
        public static readonly string _ConnectionString = new XmlUse(Application.StartupPath + "\\AIMS.xml").GetNode("ConnectionString")[0].ToString();
        /// 
        /// 执行sql操作(增、删、改)
        /// 
        /// sql语句
        /// 执行的记录数
        public static int ExecNonQuery(string sql)
        {
            using (SqlConnection conn = new SqlConnection(_ConnectionString))
            {
                if (conn.State != ConnectionState.Open)
                    conn.Open();
                using (SqlCommand cmd = conn.CreateCommand())
                {
                    cmd.Parameters.Clear();
                    cmd.CommandText = sql;
                    return cmd.ExecuteNonQuery();
                }
            }
        }
        /// 
        /// 执行sql操作(增、删、改),以参数方式传值
        /// 
        /// sql语句
        /// 参数数组
        /// 执行的记录数
        public static int ExecNonQuery(string sql, params SqlParameter[] values)
        {
            using (SqlConnection conn = new SqlConnection(_ConnectionString))
            {
                if (conn.State != ConnectionState.Open)
                    conn.Open();
                using (SqlCommand cmd = conn.CreateCommand())
                {
                    cmd.Parameters.Clear();
                    cmd.CommandText = sql;
                    cmd.Parameters.AddRange(values);
                    return cmd.ExecuteNonQuery();
                }
            }
        }
        /// 
        /// 执行sql查询,得到单个值
        /// 
        /// 得到单个值的sql查询语句
        /// 单个值对象
        public static object ExecuteScalar(string safeSql)
        {
            using (SqlConnection conn = new SqlConnection(_ConnectionString))
            {
                if (conn.State != ConnectionState.Open)
                    conn.Open();
                using (SqlCommand cmd = conn.CreateCommand())
                {
                    cmd.Parameters.Clear();
                    cmd.CommandText = safeSql;
                    return cmd.ExecuteScalar();
                }
            }
        }
        /// 
        /// 执行sql查询,得到单个值,以参数方式传值
        /// 
        /// 得到单个值的sql查询语句
        /// 参数数组
        /// 单个值对象
        public static object ExecuteScalar(string safeSql, params SqlParameter[] values)
        {
            using (SqlConnection conn = new SqlConnection(_ConnectionString))
            {
                if (conn.State != ConnectionState.Open)
                    conn.Open();
                using (SqlCommand cmd = conn.CreateCommand())
                {
                    cmd.Parameters.Clear();
                    cmd.CommandText = safeSql;
                    cmd.Parameters.AddRange(values);
                    return cmd.ExecuteScalar();
                }
            }
        }
        ///// 
        ///// 执行sql查询,得到一个DataReader对象
        ///// 
        ///// sql查询语句
        ///// DataReader对象
        //public static SqlDataReader GetDataReader(string sql)
        //{
        //    using (SqlConnection conn = new SqlConnection(_ConnectionString))
        //    {
        //        if (conn.State != ConnectionState.Open)
        //            conn.Open();
        //        SqlCommand cmd = new SqlCommand(sql, conn);
        //        SqlDataReader reader = cmd.ExecuteReader(CommandBehavior.CloseConnection); 
        //        return reader;
        //    }
        //}
        /// 
        ///  执行sql查询,得到一个DataReader对象,以参数方式传值
        /// 
        /// sql查询语句
        /// 参数数组
        /// DataReader对象
        public static SqlDataReader GetDataReader(string sql, params SqlParameter[] values)
        {
            using (SqlConnection conn = new SqlConnection(_ConnectionString))
            {
                if (conn.State != ConnectionState.Open)
                    conn.Open();
                SqlCommand cmd = new SqlCommand(sql, conn);
                cmd.Parameters.AddRange(values);
                SqlDataReader reader = cmd.ExecuteReader(CommandBehavior.CloseConnection);
                return reader;
            }
        }
        /// 
        /// 执行sql查询,得到一个DataTable对象
        /// 
        /// sql查询语句
        /// DataTable
        public static DataTable GetDataTable(string sql)
        {
            using (SqlConnection conn = new SqlConnection(_ConnectionString))
            {
                if (conn.State != ConnectionState.Open)
                    conn.Open();
                DataSet ds = new DataSet();
                SqlCommand cmd = new SqlCommand(sql, conn);
                SqlDataAdapter da = new SqlDataAdapter(cmd);
                da.Fill(ds);
                return ds.Tables[0];
            }
        }
        /// 
        /// 执行sql查询,得到一个DataTable对象,以参数方式传值
        /// 
        /// sql查询语句
        /// 参数数组
        /// DataTable
        public static DataTable GetDataTable(string sql, params SqlParameter[] values)
        {
            using (SqlConnection conn = new SqlConnection(_ConnectionString))
            {
                if (conn.State != ConnectionState.Open)
                    conn.Open();
                DataSet ds = new DataSet();
                SqlCommand cmd = new SqlCommand(sql, conn);
                if (values != null)
                    cmd.Parameters.AddRange(values);
                SqlDataAdapter da = new SqlDataAdapter(cmd);
                try
                {
                    da.Fill(ds);
                }
                catch (Exception)
                {
                }
                return ds.Tables[0];
            }
        }
        /// 
        /// 执行sql查询,得到一个DataSet对象
        /// 
        /// sql查询语句
        /// DataSet
        public static DataSet GetDataSet(string sql)
        {
            using (SqlConnection conn = new SqlConnection(_ConnectionString))
            {
                if (conn.State != ConnectionState.Open)
                    conn.Open();
                DataSet ds = new DataSet();
                SqlCommand cmd = new SqlCommand(sql, conn);
                SqlDataAdapter da = new SqlDataAdapter(cmd);
                try
                {
                    da.Fill(ds);
                }
                catch (Exception)
                {
                }
                return ds;
            }
        }
        /// 
        /// 执行sql查询,得到一个DataSet对象,以参数方式传值
        /// 
        /// sql查询语句
        /// 参数数组
        /// DataSet
        public static DataSet GetDataSet(string sql, params SqlParameter[] values)
        {
            using (SqlConnection conn = new SqlConnection(_ConnectionString))
            {
                if (conn.State != ConnectionState.Open)
                    conn.Open();
                DataSet ds = new DataSet();
                SqlCommand cmd = new SqlCommand(sql, conn);
                if (values != null)
                    cmd.Parameters.AddRange(values);
                SqlDataAdapter da = new SqlDataAdapter(cmd);
                try
                {
                    da.Fill(ds);
                }
                catch (Exception)
                {
                }
                return ds;
            }
        }
        /// 
        /// 事务
        /// 
        /// 
        /// 
        public static bool ExecuteTrasaction(string sqlStr)
        {
            bool result = true;
            using (SqlConnection conn = new SqlConnection(_ConnectionString))
            {
                if (conn.State != ConnectionState.Open)
                    conn.Open();
                SqlTransaction tran = null;
                try
                {
                    tran = conn.BeginTransaction("Tran");
                    SqlCommand cmd = new SqlCommand(sqlStr, conn, tran);
                    cmd.ExecuteNonQuery();
                    tran.Commit();
                    result = true;
                }
                catch
                {
                    tran.Rollback();
                    result = false;
                }
            }
            return result;
        }
        /// 
        /// 事务
        /// 
        /// 
        /// 
        public static bool ExecuteTrasaction(List sqlStr)
        {
            bool result = true;
            using (SqlConnection conn = new SqlConnection(_ConnectionString))
            {
                if (conn.State != ConnectionState.Open)
                    conn.Open();
                SqlTransaction tran = null;
                try
                {
                    tran = conn.BeginTransaction("Tran");
                    for (int i = 0; i < sqlStr.Count; i++)
                    {
                        SqlCommand cmd = new SqlCommand(sqlStr[i], conn, tran);
                        cmd.ExecuteNonQuery();
                    }
                    tran.Commit();
                    result = true;
                }
                catch
                {
                    tran.Rollback();
                    result = false;
                }
            }
            return result;
        }
        /// 
        /// 拆箱获得int
        /// 
        /// 
        /// 
        public static int GetInt(object obj)
        {
            return (int)obj;
        }
        /// 
        /// 拆箱获得float
        /// 
        /// 
        /// 
        public static float GetFloat(object obj)
        {
            return (float)obj;
        }
        /// 
        /// 拆箱获得double
        /// 
        /// 
        /// 
        public static double GetDouble(object obj)
        {
            return (double)obj;
        }
        /// 
        /// 拆箱获得long
        /// 
        /// 
        /// 
        public static long GetLong(object obj)
        {
            return (long)obj;
        }
        /// 
        /// 拆箱获得decimal
        /// 
        /// 
        /// 
        public static decimal GetDecimal(object obj)
        {
            return (decimal)obj;
        }
        /// 
        /// 拆箱获得bool
        /// 
        /// 
        /// 
        public static bool GetBoolean(object obj)
        {
            return (bool)obj;
        }
        /// 
        /// 拆箱获得DateTime
        /// 
        /// 
        /// 
        public static DateTime GetDateTime(object obj)
        {
            return (DateTime)obj;
        }
        /// 
        /// 拆箱获得string
        /// 
        /// 
        /// 
        public static string GetString(object obj)
        {
            return obj + "";
        }
        public static DateTime SystemDate()
        {
            string sqlStr = "select getdate() as SysDate";
            DataTable dt = GetDataTable(sqlStr);
            return DateTime.Parse(DateTime.Parse(dt.Rows[0]["SysDate"].ToString()).ToString("yyyy-MM-dd HH:mm:ss"));
        }
        public static bool QuickOpen(int timeout)
        {
            // We'll use a Stopwatch here for simplicity. A comparison to a stored DateTime.Now value could also be used
            Stopwatch sw = new Stopwatch();
            bool connectSuccess = false;
            // Try to open the connection, if anything goes wrong, make sure we set connectSuccess = false
            Thread t = new Thread(delegate ()
            {
                try
                {
                    sw.Start();
                    using (SqlConnection conn = new SqlConnection(_ConnectionString))
                    {
                        conn.Open();
                        connectSuccess = true;
                    }
                }
                catch (Exception)
                { }
            });
            // Make sure it's marked as a background thread so it'll get cleaned up automatically
            t.IsBackground = true;
            t.Start();
            // Keep trying to join the thread until we either succeed or the timeout value has been exceeded
            while (timeout > sw.ElapsedMilliseconds)
                if (t.Join(1))
                    break;
            return connectSuccess;
            //// If we didn't connect successfully, throw an exception
            //if (!connectSuccess)
            //    throw new Exception("Timed out while trying to connect.");
        }
        public static object Get(string sql, object obj, int id)
        {
            SqlCommand cmd = new SqlCommand();
            SqlConnection conn = new SqlConnection(_ConnectionString);
            PrepareCommand(cmd, conn, sql, null);
            SqlDataReader reader = cmd.ExecuteReader(CommandBehavior.CloseConnection);
            while (reader.Read())
            {
                foreach (PropertyInfo p in obj.GetType().GetProperties())
                {
                    if (p.Name == "OperationApplyId" || p.Name == "操作时间" || p.Name == "OpeRecord" || p.Name == "OpeInfo")
                    {
                        continue;
                    }
                    try
                    {
                        p.SetValue(obj, Convert.ChangeType(reader[p.Name], p.PropertyType), null);
                    }
                    catch (Exception)
                    {
                        //throw;
                    }
                }
            }
            return obj;
        }
        private static void PrepareCommand(SqlCommand cmd, SqlConnection conn, string cmdText, SqlParameter[] cmdParms)
        {
            if (conn.State != ConnectionState.Open)
                conn.Open();
            cmd.CommandText = cmdText;
            cmd.Connection = conn;
            cmd.CommandType = CommandType.Text;
            if (cmdParms != null)
            {
                cmd.Parameters.AddRange(cmdParms);
            }
        }
        public static SqlDataReader GetReader(string sql, params SqlParameter[] values)
        {
            SqlConnection connection = new SqlConnection(_ConnectionString);
            connection.Open();
            SqlCommand cmd = new SqlCommand(sql, connection);
            cmd.Parameters.AddRange(values);
            SqlDataReader reader = cmd.ExecuteReader(CommandBehavior.CloseConnection);
            return reader;
        }
        #region ToEntity
        /// 
        /// DataRow 转 实体
        /// 
        /// 
        /// 
        /// 
        public static T ReaderToModel(IDataReader dr, bool isReaded = false)
        {
            try
            {
                if (isReaded == false)
                {
                    if (dr.Read())
                    {
                        return R2E(dr);
                    }
                }
                else
                    return R2E(dr);
                return default(T);
            }
            catch (Exception)
            {
                return default(T);
            }
        }
        /// 
        /// SQL Reader 转 List
        /// 
        /// 
        /// 
        /// 
        public static List ReaderToList(IDataReader dr)
        {
            using (dr)
            {
                List list = new List();
                Type modelType = typeof(T);
                T model = Activator.CreateInstance();
                while (dr.Read())
                {
                    for (int i = 0; i < dr.FieldCount; i++)
                    {
                        PropertyInfo pi = modelType.GetProperty(dr.GetName(i), BindingFlags.GetProperty | BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase);
                        if (pi != null)
                        {
                            pi.SetValue(model, HackType(dr[i], pi.PropertyType), null);
                        }
                    }
                    list.Add(model);
                }
                return list;
            }
        }
        /// 
        /// 类型转换
        /// 
        /// 
        /// 
        /// 
        private static object HackType(object value, Type conversionType)
        {
            if (conversionType.IsGenericType && conversionType.GetGenericTypeDefinition().Equals(typeof(Nullable<>)))
            {
                if (value == null)
                    return null;
                if (IsNullOrDBNull(value))
                    return null;
                System.ComponentModel.NullableConverter nullableConverter = new System.ComponentModel.NullableConverter(conversionType);
                conversionType = nullableConverter.UnderlyingType;
            }
            return Convert.ChangeType(value, conversionType);
        }
        /// 
        /// DBNull 处理
        /// 
        /// 
        /// 
        private static bool IsNullOrDBNull(object obj)
        {
            return ((obj is DBNull) || string.IsNullOrEmpty(obj.ToString())) ? true : false;
        }
        /// 
        /// 将Reader中数据转换为实体
        /// 
        /// 
        /// 
        /// 
        private static T R2E(IDataReader dr)
        {
            Type modelType = typeof(T);
            T model = Activator.CreateInstance();
            for (int i = 0; i < dr.FieldCount; i++)
            {//, BindingFlags.GetProperty | BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase
                PropertyInfo pi = modelType.GetProperty(dr.GetName(i), BindingFlags.GetProperty | BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase);
                //PropertyInfo pi = modelType.GetProperty(dr.GetName(i));
                if (pi != null)
                {
                    pi.SetValue(model, HackType(dr[i], pi.PropertyType), null);
                }
            }
            return model;
        }
        #endregion
    }
}