using System;
using System.Data;
using System.Data.Common;
using System.Data.SQLite;

namespace isRoc.Data
{
    /// <summary>
    /// 数据库操作类
    /// </summary>
    public class _DbHelper : IDisposable
    {
        private SQLiteConnection _conn;
        private SQLiteCommand _cmd;
        private SQLiteTransaction _tan;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="conn">连接字符串</param>
        public _DbHelper(string conn)
        {
            _conn = new SQLiteConnection(conn);
        }

        /// <summary>
        /// 打开数据库
        /// </summary>
        public void Open()
        {
            _conn.Open();
            _cmd = _conn.CreateCommand();
        }

        /// <summary>
        /// 关闭数据库
        /// </summary>
        public void Close()
        {
            _cmd.Dispose();
            _conn.Close();
        }

        /// <summary>
        /// 开始事务操作
        /// </summary>
        public void BeginTransaction()
        {
            _tan = _conn.BeginTransaction();
            _cmd.Transaction = _tan;
        }

        /// <summary>
        /// 执行语句
        /// </summary>
        /// <param name="sql">语句</param>
        /// <param name="pars">参数</param>
        /// <returns>影响的行数</returns>
        public int ExecuteNonQuery(string sql, _DbParameter[] pars)
        {
            _cmd.Parameters.Clear();
            if (pars != null)
            {
                foreach (_DbParameter item in pars)
                {
                    DbParameter par = _cmd.CreateParameter();
                    par.ParameterName = item.Name;
                    par.DbType = item.Type;
                    par.Value = item.Value;
                    _cmd.Parameters.Add(par);
                }
            }
            _cmd.CommandText = sql;
            return _cmd.ExecuteNonQuery();
        }

        /// <summary>
        /// 执行语句
        /// </summary>
        /// <param name="sql">语句</param>
        /// <returns>影响的行数</returns>
        public int ExecuteNonQuery(string sql)
        {
            return ExecuteNonQuery(sql, null);
        }

        /// <summary>
        /// 执行数据阅读
        /// </summary>
        /// <param name="sql">语句</param>
        /// <param name="pars">参数</param>
        /// <param name="limit">数量</param>
        /// <returns>阅读对象</returns>
        public DbDataReader ExecuteReader(string sql, _DbParameter[] pars, int limit)
        {
            SQLiteDataReader reader;
            using (SQLiteCommand cmd = _conn.CreateCommand())
            {
                if (pars != null)
                {
                    foreach (_DbParameter item in pars)
                    {
                        DbParameter par = _cmd.CreateParameter();
                        par.ParameterName = item.Name;
                        par.DbType = item.Type;
                        par.Value = item.Value;
                        cmd.Parameters.Add(par);
                    }
                }
                if (limit > 0) { sql = sql + string.Format(" LIMIT {0}", limit); }
                cmd.CommandText = sql;
                reader = cmd.ExecuteReader();
            }
            return reader;
        }

        /// <summary>
        /// 执行数据阅读
        /// </summary>
        /// <param name="sql">语句</param>
        /// <param name="limit">数量</param>
        /// <returns>阅读对象</returns>
        public DbDataReader ExecuteReader(string sql, int limit)
        {
            return ExecuteReader(sql, null, limit);
        }

        /// <summary>
        /// 执行数据阅读
        /// </summary>
        /// <param name="sql">语句</param>
        /// <param name="pars">参数</param>
        /// <returns>阅读对象</returns>
        public DbDataReader ExecuteReader(string sql, _DbParameter[] pars)
        {
            return ExecuteReader(sql, pars, 0);
        }

        /// <summary>
        /// 执行数据阅读
        /// </summary>
        /// <param name="sql">语句</param>
        /// <returns>阅读对象</returns>
        public DbDataReader ExecuteReader(string sql)
        {
            return ExecuteReader(sql, null, 0);
        }

        /// <summary>
        /// 执行语句并返回第一行第一列的数据
        /// </summary>
        /// <param name="sql">语句</param>
        /// <param name="pars">参数</param>
        /// <returns>第一行第一列的数据</returns>
        public object ExecuteScalar(string sql, _DbParameter[] pars)
        {
            _cmd.Parameters.Clear();
            if (pars != null)
            {
                foreach (_DbParameter item in pars)
                {
                    DbParameter par = _cmd.CreateParameter();
                    par.ParameterName = item.Name;
                    par.DbType = item.Type;
                    par.Value = item.Value;
                    _cmd.Parameters.Add(par);
                }
            }
            _cmd.CommandText = sql;
            return _cmd.ExecuteScalar();
        }

        /// <summary>
        /// 执行语句并返回第一行第一列的数据
        /// </summary>
        /// <param name="sql">语句</param>
        /// <returns>第一行第一列的数据</returns>
        public object ExecuteScalar(string sql)
        {
            return ExecuteScalar(sql, null);
        }

        /// <summary>
        /// 配合分页使用的数据阅读
        /// </summary>
        /// <param name="tb">数据表名</param>
        /// <param name="fieldList">字段列表</param>
        /// <param name="where">条件，不含 WHERE 关键字</param>
        /// <param name="orderBy">排序针对字段</param>
        /// <param name="orderMode">排序模式：ASC 或 DESC</param>
        /// <param name="pageThis">当前分页，大于零</param>
        /// <param name="pageSize">分页大小，大于零</param>
        /// <param name="pars">参数列表</param>
        /// <param name="rows">当前语句的处理行数</param>
        /// <returns>数据阅读器</returns>
        public DbDataReader ExecutePages(string tb, string fieldList, string where, string orderBy, string orderMode, int pageThis, int pageSize, _DbParameter[] pars, ref int rows)
        {
            if (string.IsNullOrEmpty(orderBy)) { orderBy = "[ID]"; }
            //if (string.IsNullOrEmpty(orderMode)) { orderMode = "DESC"; }
            _cmd.Parameters.Clear();
            if (pars != null)
            {
                foreach (_DbParameter item in pars)
                {
                    DbParameter par = _cmd.CreateParameter();
                    par.ParameterName = item.Name;
                    par.DbType = item.Type;
                    par.Value = item.Value;
                    _cmd.Parameters.Add(par);
                }
            }
            if (pageThis < 1) { pageThis = 1; }
            where = (!string.IsNullOrEmpty(where) ? " WHERE " + where : string.Empty);
            _cmd.CommandText = string.Format("SELECT COUNT([ID]) FROM {0}{1}", tb, where);
            rows = Convert.ToInt32(_cmd.ExecuteScalar());
            int pageIndex = (pageThis - 1) * pageSize;
            string limit = pageSize > 0 ? string.Format(" LIMIT {1} OFFSET {0}", pageIndex, pageSize) : string.Empty;
            _cmd.CommandText = string.Format("SELECT {1} FROM {0}{2} ORDER BY {3} {4}{5}", tb, fieldList, where, orderBy, orderMode, limit);
            return _cmd.ExecuteReader();
        }

        /// <summary>
        /// 配合分页使用的数据阅读
        /// </summary>
        /// <param name="tb">数据表名</param>
        /// <param name="fieldList">字段列表</param>
        /// <param name="where">条件，不含 WHERE 关键字</param>
        /// <param name="orderBy">排序针对字段</param>
        /// <param name="orderMode">排序模式：ASC 或 DESC</param>
        /// <param name="pageThis">当前分页，大于零</param>
        /// <param name="pageSize">分页大小，大于零</param>
        /// <param name="rows">当前语句的处理行数</param>
        /// <returns>数据阅读器</returns>
        public DbDataReader ExecutePages(string tb, string fieldList, string where, string orderBy, string orderMode, int pageThis, int pageSize, ref int rows)
        {
            return ExecutePages(tb, fieldList, where, orderBy, orderMode, pageThis, pageSize, null, ref rows);
        }

        /// <summary>
        /// 执行语句返回数据集
        /// </summary>
        /// <param name="sql">语句</param>
        /// <returns>数据集</returns>
        public DataSet ExecuteDataSet(string sql)
        {
            DataSet result = new DataSet();
            _cmd.CommandText = sql;
            using (DbDataAdapter da = new SQLiteDataAdapter())
            {
                da.SelectCommand = _cmd;
                da.Fill(result);
            }
            return result;
        }

        /// <summary>
        /// 获取最后添加的数据字段
        /// </summary>
        /// <param name="tb">表名</param>
        /// <param name="field">字段</param>
        /// <param name="orderBy">以什么字段作为索引</param>
        /// <returns>返回的最新数据的字段值</returns>
        public object ExecuteNewField(string tb, string field, string orderBy)
        {
            if (string.IsNullOrEmpty(field)) { field = "[ID]"; }
            if (string.IsNullOrEmpty(orderBy)) { orderBy = "[ID]"; }
            _cmd.CommandText = string.Format("SELECT {1} FROM {0} ORDER BY {2} DESC LIMIT 1", tb, field, orderBy);
            return _cmd.ExecuteScalar();
        }

        /// <summary>
        /// 获取最后添加的数据字段
        /// </summary>
        /// <param name="tb">表名</param>
        /// <returns>返回的最新数据的字段值</returns>
        public object ExecuteNewField(string tb)
        {
            return ExecuteNewField(tb, null, null);
        }

        /// <summary>
        /// 提交数据库事务
        /// </summary>
        public void Commit()
        {
            _tan.Commit();
        }

        /// <summary>
        /// 从挂起状态回滚事务
        /// </summary>
        public void Rollback() { _tan.Rollback(); }

        /// <summary>
        /// 释放数据库资源
        /// </summary>
        public void Dispose()
        {
            if (_conn.State == ConnectionState.Open) { Close(); }
            _conn.Dispose();
        }
    }
}
