using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Data.Common;
using System.Data.OleDb;
using System.Data.OracleClient;
using System.Data.SqlClient;
using System.Data.SQLite;
using System.Linq;
using System.Text;

namespace Justin.FrameWork.Helper
{
    public class DBHelper
    {
        public static void TruncateTable(DbConnection conn, string tableName)
        {
            DbCommand cmd = PrepareCommand(conn, null, string.Format("truncate table {0}", tableName));
            cmd.ExecuteNonQuery();
        }
        public static int ExecuteNonQuery(DbConnection connection, string cmdText)
        {
            DbCommand cmd = PrepareCommand(connection, null, cmdText);
            return cmd.ExecuteNonQuery();
        }
        public static int ExecuteNonQuery(DbTransaction trans, string cmdText)
        {
            DbCommand cmd = PrepareCommand(trans.Connection, trans, cmdText);
            return cmd.ExecuteNonQuery();

        }
        public static object ExecuteScalar(DbConnection connection, string cmdText)
        {
            DbCommand cmd = PrepareCommand(connection, null, cmdText);
            object val = cmd.ExecuteScalar();
            return val;
        }

        public static DataTable ExecuteDataTable(DbConnection connection, string cmdText)
        {
            DbDataReader reader = ExecuteReader(connection, cmdText);
            DataTable table = ConvertDataReaderToDataTable(reader);
            return table;
        }
        /// <summary>
        ///     
        /// </summary>
        /// <param name="connection" type="System.Data.Common.DbConnection">
        ///     <para>
        ///            connection为SqlConnection时，此方法需要独占一个Connection，直到Reader.CLose()
        ///     </para>
        /// </param>
        /// <param name="cmdText" type="string">
        ///     <para>
        ///         
        ///     </para>
        /// </param>
        /// <returns>
        ///     A System.Data.Common.DbDataReader value...
        /// </returns>
        public static DbDataReader ExecuteReader(DbConnection connection, string cmdText)
        {
            try
            {
                DbCommand cmd = PrepareCommand(connection, null, cmdText);
                DbDataReader rdr = cmd.ExecuteReader(CommandBehavior.CloseConnection);
                return rdr;
            }
            catch
            {
                connection.Close();
                throw;
            }
        }

        private static DbCommand PrepareCommand(DbConnection connection, DbTransaction trans, string cmdText)
        {
            if (connection.State != ConnectionState.Open)
                connection.Open();
            DbCommand cmd = connection.CreateCommand();
            cmd.CommandText = cmdText;
            cmd.CommandTimeout = 600;
            if (trans != null)
                cmd.Transaction = trans;
            cmd.CommandType = CommandType.Text;
            return cmd;
        }
        public static DataTable ConvertDataReaderToDataTable(DbDataReader reader)
        {
            try
            {
                DataTable table = new DataTable();
                int fieldCount = reader.FieldCount;
                for (int fieldIndex = 0; fieldIndex < fieldCount; ++fieldIndex)
                {
                    table.Columns.Add(reader.GetName(fieldIndex), reader.GetFieldType(fieldIndex));
                }

                table.BeginLoadData();

                object[] rowValues = new object[fieldCount];
                while (reader.Read())
                {
                    reader.GetValues(rowValues);
                    table.LoadDataRow(rowValues, true);
                }
                reader.Close();
                table.EndLoadData();

                return table;

            }
            catch (Exception ex)
            {
                throw new Exception("DataReader转换为DataTable时出错!", ex);
            }

        }


        public static void BulkInsert(DbConnection conn, string providerName, string tableName, DataTable sourceData, DataRowState state, Dictionary<string, string> columnMappings = null)
        {
            BulkCopy bulkCopy = new BulkCopy(conn.ConnectionString, BulkCopy.GetSupportedDBType(providerName));
            bulkCopy.Insert(tableName, sourceData, state, columnMappings);

        }

        public static void BulkInsert(DbConnection conn, string providerName, string tableName, DataTable sourceData, Dictionary<string, string> columnMappings = null)
        {
            BulkCopy bulkCopy = new BulkCopy(conn.ConnectionString, BulkCopy.GetSupportedDBType(providerName));
            bulkCopy.Insert(tableName, sourceData, columnMappings);

        }

        public static DbConnection GetConnection(ConnectionStringSettings connectionStringSettings)
        {
            return GetConnection(connectionStringSettings.ConnectionString, connectionStringSettings.ProviderName);
        }
        public static DbConnection GetConnection(string connectionString, string providerName)
        {
            DbConnection conn = null;
            switch (providerName)
            {
                case "System.Data.SqlClient": conn = new SqlConnection(connectionString); break;
                case "Oracle.DataAccess.Client": conn = new Oracle.DataAccess.Client.OracleConnection(connectionString); break;
                case "System.Data.OracleClient": conn = new OracleConnection(connectionString); break;
                case "System.Data.SQLite": conn = new SQLiteConnection(connectionString); break;
            }
            return conn;
        }


    }
}
