package kuchenBasar;

import java.sql.*;

import javax.swing.JOptionPane;

/**
 * 
 * @author Alfa
 * 
 */
public class DBConnection
{
  private static Connection dbConn;
  private static String     connectionString;

  /**
   * Stellt die DB-Verbindung her
   * 
   * @param classForName
   * @param connectionString
   * @param userID
   * @param password
   * @return
   */
  public static boolean connectToDatabase(
      String classForName,
      String connectionString,
      String userID,
      String password )
  {
    try
    {
      Class.forName( classForName ).newInstance();

      DBConnection.dbConn = DriverManager.getConnection( connectionString, userID, password );

      DBConnection.connectionString = connectionString;

      return true;
    }
    catch ( Exception ex )
    {
      JOptionPane.showMessageDialog(
          null,
          "Fehler beim Anmelden auf die Datenbank: " + ex.getMessage(),
          "db-Fehler",
          JOptionPane.ERROR_MESSAGE );
    }

    return false;
  }

  /**
   * Schließt die DB-Verbindung
   */
  public static void closeConnection()
  {
    if ( DBConnection.dbConn == null )
      return;

    try
    {
      DBConnection.dbConn.close();
    }
    catch ( Exception ex )
    {
      JOptionPane.showMessageDialog(
          null,
          "Fehler beim Abmelden von der Datenbank: " + ex.getMessage(),
          "db-Fehler",
          JOptionPane.ERROR_MESSAGE );
    }
    finally
    {
      DBConnection.dbConn = null;
      DBConnection.connectionString = null;
    }
  }

  public static Connection getConnection()
  {
    return DBConnection.dbConn;
  }

  public static String getConnectionString()
  {
    return DBConnection.connectionString;
  }

  /**
   * BOT, ab jetzt kein Auto-Commit mehr
   */
  public static void beginTransaction()
  {
    if ( DBConnection.dbConn == null )
      return;

    try
    {
      DBConnection.dbConn.setAutoCommit( false );
    }
    catch ( SQLException ex )
    {
      JOptionPane.showMessageDialog(
          null,
          "Fehler beim Begin of Transaction auf die Datenbank" + ex.getMessage(),
          "db-Fehler",
          JOptionPane.ERROR_MESSAGE
          );
    }
  }

  /**
   * EOT schreibt die DB-Änderungen fest und setzt den Auto-Commit wieder ein
   */
  public static void commitTransaction()
  {
    if ( DBConnection.dbConn == null )
      return;

    try
    {
      if ( DBConnection.dbConn.getAutoCommit() )
        return;

      DBConnection.dbConn.commit();

      DBConnection.dbConn.setAutoCommit( true );
    }
    catch ( Exception ex )
    {
      JOptionPane.showMessageDialog(
          null,
          "Fehler beim Commit Transaction auf die Datenbank" + ex.getMessage(),
          "db-Fehler",
          JOptionPane.ERROR_MESSAGE
          );
    }
  }

  /**
   * Rollback der Änderungen, um im Fehlerfall Konsistenz wiederherzustellen
   */
  public static void rollbackTransaction()
  {
    if ( DBConnection.dbConn == null )
      return;

    try
    {
      if ( DBConnection.dbConn.getAutoCommit() )
        return;

      DBConnection.dbConn.rollback();

      DBConnection.dbConn.setAutoCommit( true );
    }
    catch ( Exception ex )
    {
      JOptionPane.showMessageDialog(
          null,
          "Fehler beim Rollback Transaction auf die Datenbank" + ex.getMessage(),
          "db-Fehler",
          JOptionPane.ERROR_MESSAGE
          );
    }
  }

  /**
   * 
   * @param sql
   * @return
   */
  public static Object executeScalar( String sql )
  {
    Statement stmt;
    Object retValue = null;

    if ( DBConnection.dbConn == null )
      return retValue;

    try
    {
      stmt = DBConnection.dbConn.createStatement();
      ResultSet rSet = stmt.executeQuery( sql );

      rSet.next();
      retValue = rSet.getObject( 1 );
      rSet.close();
      stmt.close();
    }
    catch ( Exception ex )
    {
      JOptionPane.showMessageDialog(
          null,
          "Fehler beim ExecuteScalar Zugriff auf die Datenbank: " + ex.getMessage(),
          "db-Fehler",
          JOptionPane.ERROR_MESSAGE
          );
    }

    return retValue;
  }

  /**
   * 
   * @param sql
   * @return
   * 
   * Zweck dieser Variante ist nur die Exception, die das MainFrame auswerten kann
   */
  public static Object executeScalarCheck( String sql ) throws Exception
  {
    Statement stmt;
    Object retValue = null;

    if ( DBConnection.dbConn == null )
      return retValue;

    stmt = DBConnection.dbConn.createStatement();
    ResultSet rSet = stmt.executeQuery( sql );

    rSet.next();
    retValue = rSet.getObject( 1 );
    rSet.close();
    stmt.close();

    return retValue;
  }

  /**
   * 
   * @param sql
   * @return
   */
  public static int executeNoneQuery( String sql )
  {
    int retValue = 0;
    Statement stmt;

    if ( DBConnection.dbConn == null )
      return retValue;

    try
    {
      stmt = DBConnection.dbConn.createStatement();
      retValue = stmt.executeUpdate( sql );
      stmt.close();
    }
    catch ( Exception ex )
    {
      JOptionPane.showMessageDialog(
          null,
          "Fehler beim ExecuteNoneQuery Zugriff auf die Datenbank " + ex.getMessage(),
          "db-Fehler",
          JOptionPane.ERROR_MESSAGE
          );
    }

    return retValue;
  }

  /**
   * 
   * @param sql
   * @return
   */
  public static ResultSet executeQuery( String sql )
  {
    Statement stmt;
    ResultSet rSet = null;

    if ( DBConnection.dbConn == null )
      return rSet;

    try
    {
      stmt = DBConnection.dbConn.createStatement();
      rSet = stmt.executeQuery( sql );
    }
    catch ( Exception ex )
    {
      JOptionPane.showMessageDialog(
          null,
          "Fehler beim ExecuteQuery Zugriff auf die Datenbank" + ex.getMessage(),
          "db-Fehler",
          JOptionPane.ERROR_MESSAGE
          );
    }

    return rSet;
  }

  /**
   * 
   * @param sql
   * @return fertiges SQL-Statement
   */
  public static PreparedStatement prepareStatement( String sql )
  {
    PreparedStatement preparedStatement = null;

    if ( DBConnection.dbConn == null )
      return preparedStatement;

    try
    {
      preparedStatement = DBConnection.dbConn.prepareStatement( sql );
    }
    catch ( Exception ex )
    {
      JOptionPane.showMessageDialog(
          null,
          "Fehler beim Vorbereiten des Statements" + ex.getMessage(),
          "db-Fehler",
          JOptionPane.ERROR_MESSAGE
          );
    }

    return preparedStatement;
  }
}