using System;
using System.Collections.Generic;
using System.Data.SQLite;
using System.Linq;
using System.Text;
using DataParameter = System.Data.SQLite.SQLiteParameter;
using DataCommand = System.Data.SQLite.SQLiteCommand;
using DataAdapter = System.Data.SQLite.SQLiteDataAdapter;
using System.Windows.Forms;

namespace ryCommonDb
{
    /// <summary>
    /// 
    /// </summary>
    public class SQLiteDataProvider : IDbInterface
    {
        /// <summary>
        /// 
        /// </summary>
        readonly ryCommonDb.ClsDb myDb = new ryCommonDb.ClsDb();
        /// <summary>
        /// 
        /// </summary>
        /// <param name="sql"></param>
        /// <returns></returns>
        public int ConnDb(string sql)
        {
            string[] item = sql.Split('|');
            if (item.Length == 1)
            {
                return myDb.ConnDb(sql.Replace("<app>",Application.StartupPath),"");
            }
            else
            { return myDb.ConnDb(item[0].Replace("<app>", Application.StartupPath), item[1]); }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public int CloseDb()
        {
            myDb.CloseDb();
            return 1;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="tableName"></param>
        /// <param name="wheresql"></param>
        /// <returns></returns>
        public int GetCount(string tableName, string wheresql)
        {
            string m_where = "";
            if (wheresql != "")
            {
                m_where = " where " + wheresql;
            }
            string sql= "select count(*) from "+ tableName + m_where; 
            return Convert.ToInt32(myDb.ExecuteSQL(sql,(DataParameter[])GetParameter(), "0")[0]);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="newPwd"></param>
        /// <returns></returns>
        public int ChangePwd(string newPwd)
        {
            myDb.ChangePwd(newPwd);
            return 1;
        }
        private readonly List<SQLIitem> list_param = new List<SQLIitem>();
        /// <summary>
        /// 
        /// </summary>
        /// <param name="name"></param>
        /// <param name="value"></param>
        public void AddParameter(string name,object value)
        {
            list_param.Add(new SQLIitem(name, value));
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="name"></param>
        /// <param name="value"></param>
        public void ClearParameter(object name, object value)
        {
            list_param.Clear();
        }
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public object[] GetParameter()
        {
            DataParameter[] defPar = new DataParameter[list_param.Count];
            for (int i = 0; i < list_param.Count; i++)
            {
                SQLIitem item = (SQLIitem)list_param[i];
                defPar[i] = new DataParameter("@" + item.Field.TrimStart('@').TrimStart('[').TrimEnd(']'), item.value);
            }
            return defPar;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="mySQL"></param>
        /// <returns></returns>
        public object[] GetParameter(RyQuickSQL mySQL)
        {
            DataParameter[] defPar = new DataParameter[mySQL.List.Count + mySQL.List_param.Count];
            for (int i = 0; i < mySQL.List.Count; i++)
            {
                SQLIitem item = (SQLIitem)mySQL.List[i];
                defPar[i] = new DataParameter("@" + item.Field.TrimStart('@').TrimStart('[').TrimEnd(']'), item.value);
            }
            for (int i = mySQL.List.Count; i < mySQL.List.Count + mySQL.List_param.Count; i++)
            {
                SQLIitem item = (SQLIitem)mySQL.List_param[i - mySQL.List.Count];
                defPar[i] = new DataParameter("@" + item.Field.TrimStart('@').TrimStart('[').TrimEnd(']'), item.value);
            }
            return defPar;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="tableName"></param>
        /// <param name="wheresql"></param>
        /// <param name="orderSQL"></param>
        /// <returns></returns>
        public string GetPageSQL(string tableName, string wheresql, string orderSQL)
        {
            return GetPageSQL("*", tableName, wheresql, orderSQL);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="tableName"></param>
        /// <param name="wheresql"></param>
        /// <param name="orderSQL"></param>
        /// <returns></returns>
        public string GetPageSQL2(string tableName, string wheresql, string orderSQL)
        {
            return "";
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="field"></param>
        /// <param name="tableName"></param>
        /// <param name="wheresql"></param>
        /// <param name="orderSQL"></param>
        /// <returns></returns>
        public string GetPageSQL(string field,string tableName, string wheresql, string orderSQL)
        {
            string m_where = "";
            if (wheresql != "")
            {
                m_where = " where " + wheresql;
            }
            string m_order = "";
            if (orderSQL != "")
            {
                m_order = " " + orderSQL;
            }
            return "select "+ field + " from " + tableName + m_where + m_order + " limit {pagesize} offset {recordnum}";
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="field"></param>
        /// <param name="tableName"></param>
        /// <param name="wheresql"></param>
        /// <param name="orderSQL"></param>
        /// <returns></returns>
        public string GetPageSQL2(string field,string tableName, string wheresql, string orderSQL)
        {
            return "";
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="sql"></param>
        /// <param name="Parameter"></param>
        /// <returns></returns>
        public bool ContainsData(string sql, object[] Parameter)
        {
            System.Data.DataSet ds=ReadData(sql, Parameter);
            if (ds != null && ds.Tables.Count > 0 && ds.Tables[0].Rows.Count > 0)
            {
                return true;
            }
            return false;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="sql"></param>
        /// <param name="Parameter"></param>
        /// <returns></returns>
        public System.Data.DataSet ReadData(string sql, object[] Parameter)
        {
            DataCommand cmd = myDb.SQLite_cn.CreateCommand();
            cmd.Parameters.Clear();
            if (Parameter != null)
                cmd.Parameters.AddRange(Parameter);
            cmd.CommandText = sql;
            DataAdapter ad = new DataAdapter(cmd);
            System.Data.DataSet ds=new System.Data.DataSet();
            ad.Fill(ds);
            ad.Dispose();
            cmd.Dispose();
            return ds;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="sql"></param>
        /// <param name="mySQL"></param>
        /// <returns></returns>
        public System.Data.DataSet ReadData(string sql, RyQuickSQL mySQL)
        {
            return ReadData(sql, GetParameter(mySQL));
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="sql"></param>
        /// <returns></returns>
        public System.Data.DataSet ReadData(string sql)
        {
            object[] Parameter = null;
            return ReadData(sql, Parameter);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="tableName"></param>
        /// <param name="id"></param>
        /// <returns></returns>
        public System.Data.DataSet ReadData(string tableName, string id)
        {
            object[] Parameter = null;
            return ReadData("select * from " + tableName + " where id=" + id, Parameter);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="sql"></param>
        /// <param name="Parameter"></param>
        /// <returns></returns>
        public int ExecuteNonQuery(string sql, object[] Parameter)
        {
            DataCommand cmd = myDb.SQLite_cn.CreateCommand();
            cmd.Parameters.Clear();
            if(Parameter!=null)
            cmd.Parameters.AddRange(Parameter);
            cmd.CommandText = sql;
            int i= cmd.ExecuteNonQuery();
            cmd.Dispose();
            return i;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="sql"></param>
        /// <param name="mySQL"></param>
        /// <returns></returns>
        public int ExecuteNonQuery(string sql, RyQuickSQL mySQL)
        {
            return ExecuteNonQuery(sql, GetParameter(mySQL));
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="sql"></param>
        /// <returns></returns>
        public int ExecuteNonQuery(string sql)
        {
            object[] pram = null;
            return ExecuteNonQuery(sql, pram);
        }
        SQLiteTransaction tr;
        /// <summary>
        /// 
        /// </summary>
        public void BeginTransaction()
        {
            tr= myDb.SQLite_cn.BeginTransaction();
        }
        /// <summary>
        /// 
        /// </summary>
        public void Commit()
        {
            tr.Commit();
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="tableName"></param>
        /// <param name="id"></param>
        /// <returns></returns>
        public int DelById(string tableName, string id)
        {
            object[] param = null;
            return ExecuteNonQuery("delete from " + tableName + " where id=" + id, param);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="mySQL"></param>
        /// <returns></returns>
        public int CreateDb(RyQuickSQL mySQL)
        {
            bool table_exist;
            DataCommand cmd = myDb.SQLite_cn.CreateCommand();
            cmd.Parameters.Clear();
            cmd.CommandText = "SELECT COUNT(*) FROM sqlite_master where type='table' and name='" + mySQL.TableName + "'";
            if (0 == Convert.ToInt32(cmd.ExecuteScalar()))
            {
                table_exist = false;
            }
            else
            {
                table_exist = true;
            }
            cmd.Dispose();
            if (table_exist)
            {
                System.Data.DataSet ds = ReadData("select * from " + mySQL.TableName + " limit 1");                
                for (int i = 0; i < mySQL.List.Count; i++)
                {
                    #region 循环表字段，如果不存在就创建
                    SQLIitem item = (SQLIitem)mySQL.List[i];
                    if (ds.Tables[0].Columns.Contains(item.Field))
                    { continue; }
                    string Field = "";
                    if (item.value is string)
                    {
                        Field = "[" + item.Field.TrimStart('[').TrimEnd(']') + "] TEXT COLLATE NOCASE";
                    }
                    else if (item.value is int || item.value is Int64)
                    {
                        Field = "[" + item.Field.TrimStart('[').TrimEnd(']') + "] INTEGER DEFAULT 0";
                    }
                    else if (item.value is double || item.value is float)
                    {
                        Field = "[" + item.Field.TrimStart('[').TrimEnd(']') + "] FLOAT DEFAULT 0";
                    }
                    else if (item.value is DateTime)
                    {
                        Field = "[" + item.Field.TrimStart('[').TrimEnd(']') + "] DATETIME";
                    }
                    else if (item.value is byte[])
                    {
                        Field = "[" + item.Field.TrimStart('[').TrimEnd(']') + "] BLOB";
                    }
                    try
                    {
                        object[] param = null;
                        ExecuteNonQuery("ALTER TABLE " + mySQL.TableName + " ADD COLUMN " + Field, param);
                    }
                    catch (Exception) { } 
                    #endregion
                }
                return 1;
            }
            else
            {
                #region 创建表
                string tmpSQL = "CREATE TABLE " + mySQL.TableName + " ([ID] INTEGER PRIMARY KEY,";
                for (int i = 0; i < mySQL.List.Count; i++)
                {
                    SQLIitem item = (SQLIitem)mySQL.List[i];
                    if (item.value is string)
                    {
                        tmpSQL += "[" + item.Field.TrimStart('[').TrimEnd(']') + "] TEXT COLLATE NOCASE,";
                    }
                    else if (item.value is int || item.value is Int64)
                    {
                        tmpSQL += "[" + item.Field.TrimStart('[').TrimEnd(']') + "] INTEGER DEFAULT 0,";
                    }
                    else if (item.value is double || item.value is float)
                    {
                        tmpSQL += "[" + item.Field.TrimStart('[').TrimEnd(']') + "] FLOAT DEFAULT 0,";
                    }
                    else if (item.value is DateTime)
                    {
                        tmpSQL += "[" + item.Field.TrimStart('[').TrimEnd(']') + "] DATETIME,";
                    }
                    else if (item.value is byte[])
                    {
                        tmpSQL += "[" + item.Field.TrimStart('[').TrimEnd(']') + "] BLOB,";
                    }
                }
                object[] param = null;
                return ExecuteNonQuery(tmpSQL.Substring(0, tmpSQL.Length - 1) + ")", param); 
                #endregion
            }
        }
        /// <summary>
        /// 
        /// </summary>
        public void Free()
        {
            list_param.Clear();
            myDb.CloseDb();
        }
    }
}
