using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SQLite;

namespace Common.Data.SqlLite
{
    /// <summary>
    /// 功能:SQLServer事务操作类
    /// 作者:王昊昇
    /// 时间:2012.2.8
    /// </summary>
    public class SqlLiteRoutine : IDataRoutine
    {
        /// <summary>
        /// 使用一个已打开的数据源连接创建事务实例
        /// </summary>
        /// <param name="conn"></param>
        public SqlLiteRoutine(IDbConnection conn)
        {
            this.conn = conn;

            usePooling = true;

            BeginTrans();
        }

        /// <summary>
        /// 使用一个数据源连接字符串创建数据连接并创建事务实例
        /// </summary>
        /// <param name="connStr"></param>
        public SqlLiteRoutine(string connStr)
        {
            conn = new SQLiteConnection(connStr);
            conn.Open();

            BeginTrans();
        }

        private IDbConnection conn = null;
        private IDbCommand comm = null;
        private SQLiteTransaction trans = null;
        private bool usePooling = false;//是否是使用的连接池的资源

        /// <summary>
        /// 开始事务
        /// </summary>
        private void BeginTrans()
        {
            this.comm = new SQLiteCommand();
            this.comm.Connection = this.conn;

            this.trans = (SQLiteTransaction)conn.BeginTransaction();
            this.comm.Transaction = trans;
        }

        /// <summary>
        /// 处理命令
        /// </summary>
        /// <param name="txt">命令</param>
        /// <param name="param">参数</param>
        private void PrepareCommand(string txt, IDataParameter[] param)
        {
            if (param != null)
            {
                foreach (IDataParameter parm in param)
                {
                    comm.Parameters.Add(parm);
                }
            }
        }

        /// <summary>
        /// 执行更新语句,失败时回滚操作
        /// </summary>
        /// <param name="sql">更新语句</param>
        /// <param name="param">参数列表</param>
        /// <returns></returns>
        public int ExecuteSql(string sql, params System.Data.IDataParameter[] param)
        {
            PrepareCommand(sql, param);
            
            try
            {
                return comm.ExecuteNonQuery();
            }
            catch (Exception ex)
            {
                trans.Rollback();

                throw ex;
            }
            finally
            {
                comm.Parameters.Clear();
            }
        }

        /// <summary>
        /// 执行更新语句,失败时回滚操作
        /// </summary>
        /// <param name="sql">更新语句</param>
        /// <returns></returns>
        public int ExecuteSql(string sql)
        {
            comm.CommandText = sql;
            try
            {
                return comm.ExecuteNonQuery();
            }
            catch (Exception ex)
            {
                trans.Rollback();

                throw ex;
            }
        }

        /// <summary>
        /// 执行查询语句,返回查询结果的第一行第一列的数据。失败时回滚操作
        /// </summary>
        /// <param name="sql">查询语句</param>
        /// <returns>结果对象</returns>
        public object GetSingle(string sql)
        {
            try
            {
                object obj = comm.ExecuteScalar();

                if ((Object.Equals(obj, null)) || (Object.Equals(obj, System.DBNull.Value)))
                {
                    return null;
                }
                else
                {
                    return obj;
                }
            }
            catch (Exception ex)
            {
                trans.Rollback();

                throw ex;
            }
        }

        /// <summary>
        /// 执行带参数的查询语句,返回查询结果的第一行第一列的数据。失败时回滚操作
        /// </summary>
        /// <param name="sql">查询语句</param>
        /// <param name="param">参数</param>
        /// <returns>结果对象</returns>
        public object GetSingle(string sql, params System.Data.IDataParameter[] param)
        {
            PrepareCommand(sql, (SQLiteParameter[])param);

            try
            {
                object obj = comm.ExecuteScalar();

                if ((Object.Equals(obj, null)) || (Object.Equals(obj, System.DBNull.Value)))
                {
                    return null;
                }
                else
                {
                    return obj;
                }
            }
            catch (Exception ex)
            {
                trans.Rollback();

                throw ex;
            }
            finally
            {
                comm.Parameters.Clear();
            }
        }

        /// <summary>
        /// 执行数据处理事务。失败时回滚操作
        /// </summary>
        /// <param name="list">执行语句列表</param>
        public void ExecuteSqlTran(List<string> list)
        {
            try
            {
                foreach (var s in list)
                {
                    if (s.Trim().Length > 0)
                    {
                        comm.CommandText = s;
                        comm.ExecuteNonQuery();
                    }
                }
            }
            catch (Exception ex)
            {
                trans.Rollback();

                throw ex;
            }
        }

        /// <summary>
        /// 执行带参数的数据查询。失败时回滚操作
        /// </summary>
        /// <param name="sql">查询语句</param>
        /// <param name="param">参数</param>
        /// <returns>数据集</returns>
        public System.Data.DataSet Query(string sql, params System.Data.IDataParameter[] param)
        {
            PrepareCommand(sql, (SQLiteParameter[])param);
            using (SQLiteDataAdapter da = new SQLiteDataAdapter((SQLiteCommand)comm))
            {
                System.Data.DataSet ds = new System.Data.DataSet();

                try
                {
                    da.Fill(ds, "ds");

                    return ds;
                }
                catch (Exception ex)
                {
                    trans.Rollback();

                    ds.Dispose();
                    ds = null;

                    throw ex;
                }
                finally
                {
                    comm.Parameters.Clear();
                }
            }
        }

        /// <summary>
        /// 执行数据查询。失败时回滚操作
        /// </summary>
        /// <param name="sql">查询语句</param>
        /// <returns>数据集</returns>
        public System.Data.DataSet Query(string sql)
        {
            using (SQLiteDataAdapter da = new SQLiteDataAdapter((SQLiteCommand)comm))
            {
                comm.CommandText = sql;

                System.Data.DataSet ds = new System.Data.DataSet();

                try
                {
                    da.Fill(ds, "ds");

                    return ds;
                }
                catch (Exception ex)
                {
                    trans.Rollback();

                    ds.Dispose();
                    ds = null;

                    throw ex;
                }
            }
        }

        /// <summary>
        /// 执行数据查询。失败时回滚操作
        /// </summary>
        /// <param name="sql">查询语句</param>
        /// <returns>数据表</returns>
        public System.Data.DataTable QueryReturnDataTable(string sql)
        {
            using (SQLiteDataAdapter da = new SQLiteDataAdapter((SQLiteCommand)comm))
            {
                comm.CommandText = sql;

                System.Data.DataTable table = new System.Data.DataTable();

                try
                {
                    da.Fill(table);

                    return table;
                }
                catch (Exception ex)
                {
                    trans.Rollback();

                    table.Dispose();
                    table = null;

                    throw ex;
                }
            }
        }

        /// <summary>
        /// 执行数据查询。失败时回滚操作
        /// </summary>
        /// <param name="sql">查询语句</param>
        /// <param name="param">参数</param>
        /// <returns>数据表</returns>
        public System.Data.DataTable QueryReturnDataTable(string sql, params System.Data.IDataParameter[] param)
        {
            PrepareCommand(sql, (SQLiteParameter[])param);

            using (SQLiteDataAdapter command = new SQLiteDataAdapter((SQLiteCommand)comm))
            {
                System.Data.DataTable dt = new System.Data.DataTable();

                try
                {
                    command.Fill(dt);

                    return dt;
                }
                catch (Exception ex)
                {
                    trans.Rollback();

                    dt.Dispose();
                    dt = null;

                    throw ex;
                }
                finally
                {
                    comm.Parameters.Clear();
                }
            }
        }

        /// <summary>
        /// 提交事务,关闭资源
        /// </summary>
        public void Dispose()
        {
            trans.Commit();

            trans.Dispose();
            trans = null;

            comm.Dispose();
            comm = null;

            if (!usePooling)
            {
                conn.Close();
                conn.Dispose();
                conn = null;
            }
        }

        /// <summary>
        /// 回滚事务
        /// </summary>
        public void RollBack()
        {
            trans.Rollback();
        }

        /// <summary>
        /// 提交事务
        /// </summary>
        public void Commit()
        {
            trans.Commit();
        }
    }
}