package com.corej2eepatterns.dao;

// importy

public class CustomerDAO {
  protected static final String FIELDS_INSERT = 
      "customer_name, customer_address, " + 
      "customer_contact, customer_phone, customer_email";

  protected static final String FIELDS_RETURN = 
      "customer_id, " + FIELDS_INSERT;

  protected static String INSERT_SQL =
      "insert into customer ( " + FIELDS_INSERT +
      " ) " + "values ( ?, ?, ?, ?, ?)";

  protected static String SELECT_SQL = "select " +
      FIELDS_RETURN +
      " from customer where customer_id = ? ";

  protected static String UPDATE_SQL =
      "update customer set customer_name = ?, " +
      "customer_address = ?, customer_contact = ?, " +
      "customer_phone = ?, customer_email = ? " +
      "where customer_id = ? ";

  protected static String DELETE_SQL =
      "delete from Customer where customer_id = ? ";

  // rdo danych uywane do poczenia z baz danych
  private DataSource datasource;

  public CustomerDAO() throws DAOException {
    try {
      // Przedstawione tutaj tylko ze wzgldw wyjanieniowych.
      // Zazwyczaj wyszukiwanie odbywa si przez wzorzec Service Locator
      // i obiekt DAO uywa wzorca do pobrania rda danych.
      InitialContext initialContext =
          new InitialContext();
      datasource = (DataSource) initialContext.lookup(
          OracleDAOFactory.DATASOURCE_DB_NAME);
    } catch (NamingException e) {
      throw new DAOException (
          "Nie mog odnale rda danych " + 
          DAOFactory.DATASOURCE_DB_NAME, e);
    }
  }

  public String create(CustomerTO cust) throws DAOException {
    // inicjalizacja zmiennych
    Connection con = getConnection();
    String customerId = null;

    PreparedStatement prepStmt = null;
    try {
      // instrukcja wstawiania
      prepStmt = con.prepareStatement(INSERT_SQL);
      int i = 1;
      prepStmt.setString(i++, cust.getName());
      prepStmt.setString(i++, cust.getAddress());
      . . .

      // wykonanie instrukcji
      prepStmt.executeUpdate();

      // pobranie nowej wartoci identyfikatora obiektu
      . . .

    } catch (Exception e) {
      // obsuga wyjtku
    } finally {
      // zamknicie poczenia
    }

    // zwrcenie nowej wartoci identyfikatora obiektu
    return customerId;
  }

  public CustomerTO find(String customerId)
    throws DAOException {
    // inicjalizacja zmniennych
    CustomerTO cust = null;
    Connection con = getConnection();
    PreparedStatement prepStmt = null;
    ResultSet rs = null;

    try {
      // ustawienie instrukcji i pobranie wynikw
      prepStmt = con.prepareStatement(SELECT_SQL);
      prepStmt.setString(1, customerId);
      rs = prepStmt.executeQuery();
      if (rs.next()) {
        // utworzenie obiektu transferowego z wynikami z rs
        cust = new CustomerTO();
        cust.setId(rs.getString(1));
        cust.setName(rs.getString(2));
        . . . 
      }
    } catch (Exception e) {
      // obsuga wyjtku
    } finally {
      // zamknicie poczenia
    }
    return cust;
  }

  public void update(CustomerTO cust) throws DAOException {
    Connection con = null;
    PreparedStatement prepStmt = null;
    try {
      // przygotowanie instrukcji
      con = getConnection();

      prepStmt = con.prepareStatement(UPDATE_SQL);
      int i = 1;

      // najpierw dodanie pl
      prepStmt.setString(i++, cust.getName());
      prepStmt.setString(i++, cust.getAddress());
      . . .

      // dodanie parametw where
      prepStmt.setString(i++, cust.getId());
      int rowCount = prepStmt.executeUpdate();
      prepStmt.close();
      if (rowCount == 0) {
        throw new DAOException(
          "Bd aktualizacji, idnetyfikator klienta:" + cust.getId());
      }
    } catch (Exception e) {
      // obsuga wyjtku
    } finally {
      // zamknicie poczenia
    }
  }

  public void delete(String customerId) throws Exception {
    // ustawienie zmiennych
    Connection con = getConnection();
    PreparedStatement prepStmt = null;

    try {
      // dokonanie aktualizacji bazy
      prepStmt = con.prepareStatement(DELETE_SQL);
      prepStmt.setString(1, customerId);
      prepStmt.executeUpdate();
    } catch (Exception e) {
      // obsuga wyjtku
    } finally {
      // zamknicie poczenia
    }
  }

  // pozostae metody znajdowania itp.
  . . .
}