package combd;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
import java.sql.PreparedStatement;
//import java.sql.CallableStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
//import java.sql.SQLWarning;
/**
 *   Fornece metodos para efetuar a conexão com o banco de dados, desconexão,
 * criação de Statements.
 *
 * @author Marcos V. S. Godinho
 */
public class BancoDeDados{

    private static BancoDeDados bancoDeDados;
    protected static Connection conexao;

    /** Instâcia única dessa classe. */
    private BancoDeDados(){}


    /** Finalizador da instância da classe. */
    protected void finalize() throws Throwable{

        bancoDeDados = null;//Marca Para coleta de lixo.
        //A variavel conexao é setada como null na desconexão com o banco.

        /* Este objeto é finalizado com o término do programa e não necessita
        chamar o método System.runFinalization()*/
    }


    /** Retorna a instâcia única da classe. */
    protected static final BancoDeDados getBancoDeDados(){

        if( bancoDeDados == null )  bancoDeDados = new BancoDeDados();

        return bancoDeDados;
    }//getBancoDeDados


    /** Conecta ao banco de dados. */
    protected void conecta(String driver, String url, String user, String pass){

        try{

            Class.forName(driver).newInstance();

            conexao = DriverManager.getConnection( url, user, pass);

            //Método abaixo.
            //listaWarnings(conexao.getWarnings());
        }
        catch(ClassNotFoundException ex0){

            System.err.println("Falha no carregamento do drive.");
            ex0.printStackTrace();
            System.exit(1);
        }
        catch(SQLException ex1){

            System.err.println("Ocorreu um erro na tentativa de conexão com o banco de dados.");
            ex1.printStackTrace();
        }
        catch(Exception ex2){
            System.err.println("Erro!");
            ex2.printStackTrace();
        }
    }//conecta

    //PODE SER ÚTIL ...
//    private final boolean listaWarnings(SQLWarning warn) throws SQLException{
//
//	boolean existeWarnigs = false;
//
//        if (warn != null){
//
//            System.out.println ("\n *** Warning ***\n");
//            existeWarnigs = true;
//
//            while (warn != null){
//
//		System.out.println ("Status: " + warn.getSQLState());
//		System.out.println ("Mensagem: " + warn.getMessage());
//		System.out.println ("Vendedor: " +warn.getErrorCode());
//		System.out.println ("");
//		warn = warn.getNextWarning ();
//           }
//	}
//	return existeWarnigs;
//    }//listaWarnings

    /** Desconecta do banco de dados. */
    protected void desconecta(){//Não esquecer de Chamar em um finally.

        for(int i=0; i < 5; i++){//tenta até cinco vezes.
            try{

                conexao.close();
                conexao = null;

                break;//Fechamento OK.
            }
            catch(SQLException e){

                System.err.println("Houve um erro na tentativa de desconexão com o banco de dados.");
                e.printStackTrace();
            }
        }//for
    }//desconecta


    /**
     * Prepara um <code>Statement</code>.
     * @return o <code>Statement</code>. Retorna <code>null</code> se houver erro.
     */
    protected Statement preparaStatement(){

        try{
            return conexao.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
                    ResultSet.CONCUR_READ_ONLY);

        }
        catch(SQLException ex){

            System.err.println("Ocorreu um erro na criação de um Statement.");
            ex.printStackTrace();
        }

        return null;
    }//preparaStatement


    /**
     * Prepara um <code>PreparedStatement</code>.
     * @return o <code>PreparedStatement</code>. Retorna <code>null</code> se houver erro.
     */
    protected PreparedStatement preparaPrepared(String qry){

        try{
            return conexao.prepareStatement(
                    qry,//A query preparada.
                    ResultSet.TYPE_SCROLL_INSENSITIVE,
                    ResultSet.CONCUR_READ_ONLY);

        }
        catch(SQLException ex){

            System.err.println("Ocorreu um erro na criação de um PreparedStatement.");
            ex.printStackTrace();
        }

        return null;
    }//preparaPrepared
}
