using System;
using System.Data;
using System.Data.Common;
using System.Configuration;
using System.Web.Configuration;
using System.Collections.Generic;

using FourLayer.BusinessEntity;

namespace FourLayer.DataAccessObject
{
   /// <summary>
   /// Summary description for DatabaseActions
   /// </summary>
   public static class DatabaseActions
   {
      
      /// <summary>
      /// Runs a non-data returning SQL query
      /// </summary>
      public static void RunNonQuery(string sql, DbParameter[] parameters)
      {
         // create provider-independent connection
         using (DbConnection conn = Factory.CreateConnection())
         {
            conn.ConnectionString = ConnectionSetting.ConnectionString;

            // create provider-independent command
            DbCommand cmd = Factory.CreateCommand();
            cmd.Connection = conn;
            cmd.CommandText = sql;

            // add parameters
            if (parameters != null)
            {
               foreach (DbParameter p in parameters)
                  cmd.Parameters.Add(p);
            }

            try
            {
               conn.Open();
               cmd.ExecuteNonQuery();
            }
            catch (Exception ex)
            {
               // any errors will be handled by our custom exception handler
           
               DataAccessExceptionHandler.HandleException(ex.Message);
            }
         }
      }

      /// <summary>
      /// Runs a scalar returning SQL query
      /// </summary>
      public static object RunScalar(string sql, DbParameter[] parameters)
      {
         object scalar = null;

         // create provider-independent connection
         using (DbConnection conn = Factory.CreateConnection())
         {
            conn.ConnectionString = ConnectionSetting.ConnectionString;

            // create provider-independent command
            DbCommand cmd = Factory.CreateCommand();
            cmd.Connection = conn;
            cmd.CommandText = sql;

            // add parameters
            if (parameters != null)
            {
               foreach (DbParameter p in parameters)
                  cmd.Parameters.Add(p);
            }

            try
            {
               conn.Open();
               scalar = cmd.ExecuteScalar();
            }
            catch (Exception ex)
            {
               // any errors will be handled by our custom exception handler
               DataAccessExceptionHandler.HandleException(ex.Message);
            }
            return scalar;
         }
      }

      /// <summary>
      /// Private property that returns connection string setting from web.config
      /// </summary>
      public static ConnectionStringSettings ConnectionSetting
      {
         get
         {
            return WebConfigurationManager.ConnectionStrings["BookCatalog"];

         }
      }

      /// <summary>
      /// Private property to return appropriate DbProviderFactory
      /// </summary>
      public static DbProviderFactory Factory
      {
         get
         {
            string connString = ConnectionSetting.ConnectionString;
            string invariantName = ConnectionSetting.ProviderName;

            // verify that this provider name is supported
            DataTable providers = DbProviderFactories.GetFactoryClasses();
            DataRow[] foundArray = providers.Select("InvariantName='" + invariantName + "'");
            if (foundArray.Length == 0)
            {
               // any errors will be handled by our custom exception handler
               string msg = "[AbstractDA] Data Provider " + invariantName + " not found";
               DataAccessExceptionHandler.HandleException(msg);
            }

            // get appropriate provider factory
            return DbProviderFactories.GetFactory(invariantName);
         }
      }

      /// <summary>
      /// Create a provider-independent DbParameter object
      /// </summary>
      public static DbParameter MakeParameter(string name, object value, DbType paramType)
      {
         DbParameter param = MakeParameter(name, value);
         param.DbType = paramType;
         return param;
      }
      /// <summary>
      /// Create a provider-independent DbParameter object
      /// </summary>
      public static DbParameter MakeParameter(string name, object value)
      {
         DbParameter param = Factory.CreateParameter();
         param.ParameterName = name;
         param.Value = value;
         return param;
      }
   }
}