using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data;
using MySql.Data.MySqlClient;

namespace parkMonitor.Database2
{
    /// <summary>
    /// sqlCommand抽象类
    /// </summary>
    abstract class AbstractCommand
    {
        public string sql { set; get; }
        public List<string> strs { set; get; }

        public Connection conn { set; get; }
        /// <summary>
        /// 抽象类的构造函数
        /// </summary>
        public AbstractCommand()
        {
            sql = null;
            conn = null;
        }
        /// <summary>
        /// 类的构造函数
        /// </summary>
        public AbstractCommand(string sql, Connection conn)
        {
            this.sql = sql;
            this.conn = conn;
        }
        /// <summary>
        /// 创建sqlCommand
        /// </summary>
        /// <returns></returns>
        protected MySqlCommand CreateCommand()
        {
            MySqlCommand cmd = null;
            try
            {
                cmd = new MySqlCommand(sql, conn.mySqlConnection);
            }
            catch (Exception ex) {
                Console.WriteLine(ex.Message);
                Console.WriteLine("MySqlCommand异常");
                throw ex;
            }
            return cmd;
        }
        /// <summary>
        /// 根据连接创建sqlCommand
        /// </summary>
        /// <returns></returns>
        protected MySqlCommand CreateCommand(string sql, MySqlConnection mySqlConnection)
        {
            MySqlCommand cmd = null;
            try
            {
                cmd = new MySqlCommand(sql, conn.mySqlConnection);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                Console.WriteLine("MySqlCommand异常");
                throw ex;
            }
            return cmd;
        }
        /// <summary>
        /// 抽象执行方法
        /// </summary>
        /// <returns></returns>
        public abstract object ExecuteSqlCommand();

    }

    /// <summary>
    /// 查询数据库Command
    /// </summary>
    class QueryCommand : AbstractCommand
    {
        public override object ExecuteSqlCommand()
        {
            object result = null;
            try
            {
                MySqlCommand cmd = CreateCommand(sql, conn.mySqlConnection);
                result = cmd.ExecuteReader();
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                Console.WriteLine("ExecuteReader执行异常");
                throw ex;
            }
            return result;
        }
    }

    /// <summary>
    /// 插入更新数据库Command
    /// </summary>
    class NoQueryCommand : AbstractCommand
    {
        public override object ExecuteSqlCommand()
        {
            object result = null;
            try
            {
                MySqlCommand cmd = CreateCommand(sql, conn.mySqlConnection);
                result = cmd.ExecuteNonQuery();
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                Console.WriteLine("ExecuteNonQuery执行异常");
                throw ex;
            }
            return result;
        }
    }
    /// <summary>
    /// 统计个数Command
    /// </summary>
    class ScalarCommand : AbstractCommand
    {
        public override object ExecuteSqlCommand()
        {
            object result = null;
            try
            {
                MySqlCommand cmd = CreateCommand(sql, conn.mySqlConnection);
                result = cmd.ExecuteScalar();
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                Console.WriteLine("ExecuteScalar执行异常");
                if(conn != null)
                {
                    conn.Dispose();                   
                }
                ConnectionPoolManager.AddConnToPooling(1, ConnectionPoolManager.remoteConf);
                throw ex;
            }
            return result;
        }
    }
    /// <summary>
    /// 存储过程执行Command
    /// </summary>
    class StoreProcedureCommand : AbstractCommand
    {
        public override object ExecuteSqlCommand()
        {
            object result = null;
            MySqlCommand cmd = CreateCommand(sql, conn.mySqlConnection);
            cmd.CommandType = CommandType.StoredProcedure;
            //cmd.Parameters.AddWithValue();
            result = cmd.ExecuteReader();
            return result;
        }
    }

    /// <summary>
    /// 数据库事务操作Command
    /// </summary>
    class TransactionCommand : AbstractCommand
    {
        public List<string> strs { set; get; }
        /// <summary>
        /// 实务操作类的构造函数
        /// </summary>
        public TransactionCommand()
        {
            sql = null;
            conn = null;
            strs = null;
        }
        /// <summary>
        /// 实务操作类的构造函数
        /// </summary>
        /// <param name="sql"></param>
        /// <param name="conn"></param>
        /// <param name="strs"></param>
        public TransactionCommand(string sql, Connection conn, List<string> strs)
            : base(sql,conn)
        {
            this.strs = strs;
        }
        /// <summary>
        /// 事务执行
        /// </summary>
        /// <returns></returns>
        public override object ExecuteSqlCommand()
        {
            int result = 0;
            bool flag = true;
            MySqlCommand myCommand = null;
            MySqlTransaction myTrans = null;
            try
            {
                myCommand = conn.mySqlConnection.CreateCommand();                
                myTrans = conn.mySqlConnection.BeginTransaction();
                myCommand.Connection = conn.mySqlConnection;
                myCommand.Transaction = myTrans;
                for (int i = 0; i < strs.Count(); i++)
                {
                    myCommand.CommandText = strs[i];
                    myCommand.ExecuteNonQuery();
                    result = Convert.ToInt32(myCommand.LastInsertedId);
                }
                myTrans.Commit();
                flag = true;
            }
            catch (Exception e)
            {
                try
                {
                    if (myTrans != null)
                    {
                        myTrans.Rollback();
                    }
                }
                catch (MySqlException ex)
                {
                    if (myTrans.Connection != null)
                    {
                        Console.WriteLine(ex.Message + "事务回滚失败");
                    }   
                }
                flag = false;
                Console.WriteLine(e.Message + "事务操作失败");
                throw e;
            }
            finally
            {
                if (myCommand != null)
                {
                    myCommand.Dispose();
                }
                if (myTrans != null)
                {
                    myTrans.Dispose();
                }
                //ConnectionPoolManager.ReleaseConnection(conn);
            }
            TransactionResult transactionResult = new TransactionResult();
            transactionResult.result = result;
            transactionResult.flag = flag;
            return transactionResult;
        }
    }
    /// <summary>
    /// Command枚举类型
    /// </summary>
    enum CommandTypes { QUERYCOMMAND, NOQUERYCOMMAND, SCALARCOMMAND, TRANSACTIONCOMMAND, STOREPROCEDURECOMMAND };
    /// <summary>
    /// 事务执行结构
    /// </summary>
    public class TransactionResult
    {
        public int result { get; set; }
        public bool flag { get; set; }
    }
}
