/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package Logica_Operaciones_BD;


import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Vector;

/**
 *
 * @author harol
 */
public final class OperacionesCRUD 
{
    private static OperacionesCRUD lainstance = new OperacionesCRUD();
    private Connection conexion;

    private OperacionesCRUD() 
    {         
    }
    
    public static OperacionesCRUD getInstance()
    {
        return lainstance;
    }
    
    private void iniciarConexionBD()//INICIAR LA CONEXIONA LA BD
    {
        this.conexion = ConexionBD.iniciarConexion();
    }
    
    private void cerrarConexionBD() throws SQLException  //CERRAR LA CONEXION A LA BD
    {
        if (this.conexion != null && this.conexion.isClosed() == false) //valida si aun está habierta la conexion BD
        {
            this.conexion.close();
        }
    }    
    //inciso 1.
    public int obtenerCantCarreras() throws SQLException //CONSULTA 1, PARTE 1.
    {
        //1. Conectar a la base de datos
        this.iniciarConexionBD();         
        //2. Variable para almacenar el total de carreras almacenadas en la base de datos.
        int totalCarreras = 0;    
        //3. definir espacio de trabajo para la declaración y ejecución de la consulta sql
        Statement stm = this.conexion.createStatement();
        //4. Definir el texto String de la consulta SQL.
        String sql = "select count(*) as total_carreras from carreras c";        
        //5. Ejecutar la consulta y amacenar en el objeto ResultSet
        ResultSet tabla = stm.executeQuery(sql);
        //6. Recorrer el objeto ResultSet mediante un while y para cada iteración resolver:
        while(tabla.next())
        {
            totalCarreras = tabla.getInt("total_carreras");            
        }
        //7. Cerrar la conexion a la base de datos    
        this.cerrarConexionBD();        
        //8. Retornar el total de carreras que está almancenado en la base de datos
        return totalCarreras;
    }
    //inciso 2.
    public Vector<String> obtenerListadoCarreras() throws SQLException //CONSULTA 2
    {
        //1. Conectar a la base de datos
        this.iniciarConexionBD();        
        //2. Crear el vector para almacenar la lista de nombres de carreras resultante de la consulta SQL a la base de datos.
        Vector<String> listado_carreras = new Vector<>();
        //complete la lógica del bloque de código que resuelve: 
        //3. definir espacio de trabajo para la declaración y ejecución de la consulta sql
        Statement stm = this.conexion.createStatement();
        //4. Definir el texto String de la consulta SQL.
        String sql = "select c.nombre as nombres_carreras from carreras c";
        //5. Ejecutar la consulta y amacenar en el objeto ResultSet
        ResultSet tabla = stm.executeQuery(sql);
        //6. Recorrer el objeto ResultSet mediante un while y para cada iteración resolver:
        while(tabla.next())
        {
            String nombre_carrera = tabla.getString("nombres_carreras");
            listado_carreras.add(nombre_carrera);
        }
        //7. Cerrar la conexion a la base de datos       
        this.cerrarConexionBD();
        //8. Retornar el objeto vector con la lista de nombres de carreras almacenados en la base de datos
        return listado_carreras;
    }  
    //OK
    public Vector<String> obtenerListaParalelos() throws SQLException
    {
        //1. Conectar a la base de datos
        this.iniciarConexionBD();
        //2. Crear el vector para almacenar la lista de códgidos de paralelos resultante de la consulta SQL a la base de datos.
        Vector<String> lista_paralelos = new Vector<>();
        //complete la lógica del bloque de código que resuelve:
        //3. definir espacio de trabajo para la declaración y ejecución de la consulta sql
        Statement stm = this.conexion.createStatement();            
        //4. Definir el texto String de la consulta SQL.
        String sql = "select p.nombre as PARALELOS from paralelos p";                
        //5. Ejecutar la consulta y amacenar en el objeto ResultSet
        ResultSet tabla = stm.executeQuery(sql); 
        //6. Recorrer el objeto ResultSet mediante un while y para cada iteración resolver:
        while(tabla.next())
        {                    
            //6.1. Obtener el valor de columna de la fila actual del objeto ResultSet
            String valorColumna = tabla.getString("PARALELOS");                    
            //6.2. Almacenar en el vector creado en el paso 2. el valor de columna de la fila actual del objeto ResultSet
            lista_paralelos.add(valorColumna);
        }  
        //7. Cerrar la conexion a la base de datos
        this.cerrarConexionBD();
        //8. Retornar el objeto vector con la lista de códigos de paralelos almacenados en la base de datos
        return lista_paralelos;        
    }
    //Inciso 3
    public Vector<String> obtenerListaParalelosCarrera(String p_nombre_carrera) throws SQLException
    {
        //1. Conectar a la base de datos
        this.iniciarConexionBD();
        //2. Crear el vector para almacenar la lista de códgidos de paralelos resultante de la consulta SQL a la base de datos.
        Vector<String> lista_paralelos_codigo = new Vector<>();      
        //complete la lógica del bloque de código que resuelve:
        //3. definir espacio de trabajo para la declaración y ejecución de la consulta sql
        Statement stm = this.conexion.createStatement();             
        //4. Definir el texto String de la consulta SQL.
        String sql = "SELECT p.nombre, p.cod_paralelo FROM paralelos p join carreras c on p.cod_carrera = c.cod_carrera where c.nombre = '"+p_nombre_carrera+"'";
        //5. Ejecutar la consulta y amacenar en el objeto ResultSet
        ResultSet tabla = stm.executeQuery(sql); 
        //6. Recorrer el objeto ResultSet mediante un while y para cada iteración resolver:
        while(tabla.next())
        {                            
            String valorColumna = tabla.getString("nombre");                    
            lista_paralelos_codigo.add(valorColumna);
        }  
        //7. Cerrar la conexion a la base de datos
        this.cerrarConexionBD();
        //8. Retornar el objeto vector con la lista de códigos de paralelos almacenados en la base de datos
         return lista_paralelos_codigo;
    }
    //Inciso 4
    public ArrayList<Vector<String>> obtenerEstudInscritosPorCarrera(String p_nombre_carrera) throws SQLException
    {
        //1. Conectar a la base de datos
        this.iniciarConexionBD();
        //2. Crear la matriz de datos para almacenar la consulta SQL, cada fila es un Vector de String
        ArrayList<Vector<String>> consulta = new ArrayList<>();
        //3. definir espacio de trabajo para la declaración y ejecución de la consulta sql
        Statement stm = this.conexion.createStatement();  
        //4. Definir el texto String de la consulta SQL.
        String sql = "select e.cedula, e.nombres, e.apellidos from inscripciones_estudiantes i \n" +
        "JOIN estudiantes e ON (i.cedula = e.cedula)\n" +
        "JOIN carreras c ON (i.cod_carrera = c.cod_carrera) where c.nombre = '"+p_nombre_carrera+"'";
        //5. Ejecutar la consulta y amacenar en el objeto ResultSet
         ResultSet tabla = stm.executeQuery(sql);     
        //6. Recorrer el objeto ResultSet mediante un while y para cada iteración resolver:
        while(tabla.next())
        {      
            Vector datos = new Vector <>();
            String cedula = tabla.getString("cedula");         
            datos.add(cedula);
            String nombre = tabla.getString("nombres");                    
            datos.add(nombre);
            String apellido = tabla.getString("apellidos");                    
            datos.add(apellido);
            consulta.add(datos);
        
        }                        
        //7. Cerrar la conexion a la base de datos
        this.cerrarConexionBD();
        //8. Retornar la matriz de datos con los resultados de la consulta SQL.
        return consulta;
    } 
    //Inciso 5
    public ArrayList<Vector<String>> obtenerEstudInscritosPorParalelo(String p_codigo_paralelo) throws SQLException
    {
         //1. Conectar a la base de datos
        this.iniciarConexionBD();
        //2. Crear la matriz de datos para almacenar la consulta SQL, cada fila es un Vector de String
        ArrayList<Vector<String>> consulta = new ArrayList<>();
        //3. definir espacio de trabajo para la declaración y ejecución de la consulta sql
        Statement stm = this.conexion.createStatement();  
        //4. Definir el texto String de la consulta SQL.
        String sql = "select e.cedula, e.nombres, e.apellidos from inscripciones_estudiantes i \n" +
                       "JOIN estudiantes e ON (i.cedula = e.cedula)\n" +
                        "JOIN paralelos p ON (i.cod_paralelo = p.cod_paralelo ) where p.nombre = '"+p_codigo_paralelo+"'";
        //5. Ejecutar la consulta y amacenar en el objeto ResultSet
         ResultSet tabla = stm.executeQuery(sql);    
        //6. Recorrer el objeto ResultSet mediante un while y para cada iteración resolver:
         while(tabla.next())
        {      
            Vector datos = new Vector <>();
            String cedula = tabla.getString("cedula");         
            datos.add(cedula);
            String nombre = tabla.getString("nombres");                    
            datos.add(nombre);
            String apellido = tabla.getString("apellidos");                    
            datos.add(apellido);
            consulta.add(datos);
        }                                            
        //7. Cerrar la conexion a la base de datos
        this.cerrarConexionBD();
        //8. Retornar la matriz de datos con los resultados de la consulta SQL.
        return consulta;
    }
    
}
