using System;
using System.Data;
using System.Data.SqlClient;
using System.Data.SqlTypes;
using System.Security;
using System.Security.Permissions;
using System.Text;
using Microsoft.SqlServer.Server;

namespace Apress.SqlServer2005.SecurityChapter
{
   public class SalesFetcher
   {
      public static void GetSalesForNames(SqlString filename)
      {
         try
         {
            PermissionSet perms = new PermissionSet(PermissionState.None);

            // zapewnienie, że metoda pozwala na dostęp tylko do prawidłowego pliku
            FileIOPermission ioPerm = new FileIOPermission(
                 FileIOPermissionAccess.Read, @"C:\nazwiska.txt");
            perms.AddPermission(ioPerm);

            // nadanie prawa dostępu do danych SQL Servera
            SqlClientPermission sqlPerm = new SqlClientPermission(
                                                 PermissionState.None);
            sqlPerm.Add("context connection=true", "",
                        KeyRestrictionBehavior.AllowOnly);
            perms.AddPermission(sqlPerm);
            perms.PermitOnly();

            // odczytanie nazwisk z pliku tekstowego w postaci tablicy ciągów znaków
            string[] names = FileReader.ReadFile(filename.ToString());

            // utworzenie instrukcji SQL
            StringBuilder sb = new StringBuilder();
            sb.Append(@"SELECT emp.EmployeeID,
                               sp.SalesYTD + sp.SalesLastYear AS RecentSales
                        FROM Sales.SalesPerson sp
                           INNER JOIN HumanResources.Employee emp
                           ON emp.EmployeeID = sp.SalesPersonID
                        WHERE sp.SalesPersonID IN
                        (
                           SELECT emp.EmployeeID
                           FROM HumanResources.Employee emp
                              INNER JOIN Person.Contact c
                              ON c.ContactID = emp.ContactID
                           WHERE c.FirstName + ' ' + c.MiddleName + ' ' +
                                 c.LastName
                           IN (");

            // złożenie zawartości tablicy w jeden ciąg znaków dla klauzuli WHERE
            foreach (string name in names)
            {
               sb.Append("'");
               sb.Append(name);
               sb.Append("', ");
            }
            sb.Remove(sb.Length - 2, 2);
            sb.Append("))");

            // wykonanie instrukcji SQL i zwrócenie zestawu wyników SqlResultSet
            using (SqlConnection cn = new SqlConnection(
                                             "context connection=true"))
            {
               cn.Open();
               SqlCommand cmd = new SqlCommand(sb.ToString(), cn);
               SqlDataReader dr = cmd.ExecuteReader();

               // wysłanie do SQL Servera komunikatu o powodzeniu operacji i zwrócenie obiektu SqlDataReader
               SqlPipe pipe = SqlContext.Pipe;
               pipe.Send(dr);
               pipe.Send("Polecenie(a) wykonane poprawnie.");
               cn.Close();
            }
         }
         catch (Exception e)
         {
            SqlPipe pipe = SqlContext.Pipe;
            pipe.Send(e.Message);
            pipe.Send(e.StackTrace);
            pipe.Send("Błąd w trakcie wykonywania podzespołu");
         }
      }
   }
}