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>
   /// Ogólny opis DatabaseActions
   /// </summary>
   public static class DatabaseActions
   {
      
      /// <summary>
      /// Uruchamia zapytanie SQL, które nie zwraca danych
      /// </summary>
      public static void RunNonQuery(string sql, DbParameter[] parameters)
      {
         // utwórz połączenie niezależne od dostawcy
         using (DbConnection conn = Factory.CreateConnection())
         {
            conn.ConnectionString = ConnectionSetting.ConnectionString;

            // utwórz instrukcję niezależną od dostawcy
            DbCommand cmd = Factory.CreateCommand();
            cmd.Connection = conn;
            cmd.CommandText = sql;

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

            try
            {
               conn.Open();
               cmd.ExecuteNonQuery();
            }
            catch (Exception ex)
            {
               // wszystkie błędy będą obsługiwane przez niestandardową procedurę obsługi wyjątków
           
               TwoLayer.DataAccess.DataAccessExceptionHandler.HandleException(ex.Message);
            }
         }
      }

      /// <summary>
      /// Uruchamia skalar zwracający zapytanie SQL
      /// </summary>
      public static object RunScalar(string sql, DbParameter[] parameters)
      {
         object scalar = null;

         // utwórz połączenie niezależne od dostawcy
         using (DbConnection conn = Factory.CreateConnection())
         {
            conn.ConnectionString = ConnectionSetting.ConnectionString;

            // utwórz instrukcję niezależną od dostawcy
            DbCommand cmd = Factory.CreateCommand();
            cmd.Connection = conn;
            cmd.CommandText = sql;

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

            try
            {
               conn.Open();
               scalar = cmd.ExecuteScalar();
            }
            catch (Exception ex)
            {
               // wszystkie błędy będą obsługiwane przez niestandardową procedurę obsługi wyjątków
               TwoLayer.DataAccess.DataAccessExceptionHandler.HandleException(ex.Message);
            }
            return scalar;
         }
      }

      /// <summary>
      /// Właściwość prywatna zwracająca parametry łańcucha połączenia z pliku web.config
      /// </summary>
      public static ConnectionStringSettings ConnectionSetting
      {
         get
         {
            return WebConfigurationManager.ConnectionStrings["BookCatalog"];

         }
      }

      /// <summary>
      /// Właściwość prywatna zwracająca odpowiednią DbProviderFactory
      /// </summary>
      public static DbProviderFactory Factory
      {
         get
         {
            string connString = ConnectionSetting.ConnectionString;
            string invariantName = ConnectionSetting.ProviderName;

            // sprawdź, czy nazwa dostawcy jest obsługiwana
            DataTable providers = DbProviderFactories.GetFactoryClasses();
            DataRow[] foundArray = providers.Select("InvariantName='" + invariantName + "'");
            if (foundArray.Length == 0)
            {
               // wszystkie błędy będą obsługiwane przez niestandardową procedurę obsługi wyjątków
               string msg = "[AbstractDA] Data Provider " + invariantName + " not found";
               TwoLayer.DataAccess.DataAccessExceptionHandler.HandleException(msg);
            }

            // pobierz odpowiednią fabryke dostawców
            return DbProviderFactories.GetFactory(invariantName);
         }
      }

      /// <summary>
      /// Utwórz niezależny od dostawcy obiekt DbParameter
      /// </summary>
      public static DbParameter MakeParameter(string name, object value, DbType paramType)
      {
         DbParameter param = MakeParameter(name, value);
         param.DbType = paramType;
         return param;
      }
      /// <summary>
      /// Utwórz niezależny od dostawcy obiekt DbParameter
      /// </summary>
      public static DbParameter MakeParameter(string name, object value)
      {
         DbParameter param = Factory.CreateParameter();
         param.ParameterName = name;
         param.Value = value;
         return param;
      }
   }
}