package hirondelle.web4j.database;

import java.sql.*;
import java.util.logging.*;

import hirondelle.web4j.util.Util;

/**
 Static methods for relational databases, which avoid code repetition.
*/
final class DbUtil {
  
  /**
   Close a <tt>Statement</tt> first, then its associated <tt>Connection</tt>.
   <P>Parameters are permitted to be <tt>null</tt>.
  */
  static void close(PreparedStatement aStatement, Connection aConnection) throws DAOException {
    try {
      if (aStatement != null) aStatement.close();
      if (aConnection != null) aConnection.close();
    }
    catch (SQLException ex){
      throw new DAOException("Cannot close statement or connection: " + ex, ex);
    }
  }
  
  /**
   Close a possibly-null <tt>Connection</tt>.
  */
  static void close(Connection aConnection) throws DAOException {
    close(null, aConnection);
  }
    
  /** Close a possibly-null <tt>Statement</tt>.  */
  static void close(PreparedStatement aStatement) throws DAOException {
    close(aStatement, null);
  }
  
  /**
   If <tt>aStatement</tt> has any warnings, then log them using "severe" level.
  */
  static void logWarnings(Statement aStatement) {
    try {
      SQLWarning warning = aStatement.getWarnings();
      logWarning(warning);
    }
    catch (SQLException exception) {
      //do nothing, since not critical
    }
  }
  
  /**
   If <tt>aConnection</tt> has any warnings, then log them using "severe" level.
  */
  static void logWarnings(Connection aConnection) {
    try {
      SQLWarning warning = aConnection.getWarnings();
      logWarning(warning);
    }
    catch (SQLException exception) {
      //do nothing, since not critical
    }
  }
  
  // PRIVATE //
  
  private static final Logger fLogger = Util.getLogger(DbUtil.class);  
  
  private static void logWarning(SQLWarning aWarning){
    //minor optimisation for the nominal case
    if (aWarning == null) return;

    final StringBuilder message = new StringBuilder();
    SQLWarning warning = aWarning;
    while ( warning!= null ){
      message.append("***SQL WARNING***: ");
      message.append( warning );
      message.append(" SQL ErrorId Code:");
      message.append( warning.getErrorCode() );
      message.append(" SQL State:");
      message.append( warning.getSQLState());
      warning = warning.getNextWarning();
    }
    fLogger.severe(message.toString());
  }
}
