/* 
* Copyright 2016 Agencia Estatal de Administración Tibutaria
*
* Licencia con arreglo a la EUPL, Versión 1.1 o –en cuanto
* sean aprobadas por la Comisión Europea– versiones
* posteriores de la EUPL (la «Licencia»);
* Solo podrá usarse esta obra si se respeta la Licencia.
* Puede obtenerse una copia de la Licencia en:
*  
* https://joinup.ec.europa.eu/software/page/eupl
*  
* Salvo cuando lo exija la legislación aplicable o se acuerde
* por escrito, el programa distribuido con arreglo a la
* Licencia se distribuye «TAL CUAL», SIN GARANTÍAS NI CONDICIONES
* DE NINGÚN TIPO, ni expresasni implícitas.
*
* Véase la Licencia en el idioma concreto que rige los permisos y 
* limitaciones que establece la Licencia.
*/ 


package servidor.datos;

import java.sql.*;

import servidor.utiles.*;
import java.util.*;


public class Tabla_Base {
   
   Connection conexion;
   public ResultSet rs;
   ResultSetMetaData metadata;
   DatabaseMetaData dbmeta;
   HashMap registro;
   String[][] datoscol;
   String tabla;
   int numColumnas;
   String sql;
   Statement stmt;
   
   public Tabla_Base(Connection conexion, String nombreTabla) {
	  this.conexion = conexion;
	  tabla = nombreTabla;
   }
   
   public void borrarTabla() throws SQLException {
	  SQL("DELETE * FROM " + tabla);
   }
   
   public void cerrar() {
	  try {
		 rs.close();
	  } catch(Exception exc) {
		  Global.log.warning("No se pudo cerrar " + tabla);
	  }
   }
   
   public void leerDatos() {
	  leerDatos(null);
   }
   
   public void leerDatos(String filtro) {
	  String nomcampo; 
	  try {
		 stmt = conexion.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
		 sql = "SELECT * FROM " + tabla;
		 if(filtro != null) {
			sql += " " + filtro;
		 }
		 
		 rs = stmt.executeQuery(sql);
		 
		 metadata = rs.getMetaData();
		 numColumnas = metadata.getColumnCount();
		 datoscol=new String[numColumnas][2];
		 registro=new HashMap();
		
		   for (int i=0;i<numColumnas;i++){
		      nomcampo=metadata.getColumnName(i+1);	
			  registro.put(nomcampo,null);
			  datoscol[i][0]=nomcampo;
			  datoscol[i][1]=metadata.getColumnClassName(i+1);
			  }
		
	  } catch(Exception e) {
		  Global.log.severe("ERROR en acceso a BD.");
	  }
   }
   
   public void releer() {
	  try {
		 Statement stmt = conexion.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
		 rs = stmt.executeQuery(sql);
	  } catch(Exception e)  {
		  Global.log.severe("ERROR en acceso a BD.");
	  }
   }
   
   public int recordsCount() {
	   
	  try {
		 Statement stmt = conexion.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
		 rs.last();
		 //s=stmt.executeQuery("select count(*) as 'cuenta' from "+tabla);
		 //rs.next();
		 //return rs.getInt(1);
		 return rs.getRow();
	  } catch(Exception e) {
		 return -1;
	  }
   }
   
   public int columnCount() {
	  return numColumnas;
   }
   private void leerRegistro() throws SQLException{
	   
	   if (rs.isAfterLast() || rs.isBeforeFirst() || rs.getRow()==0){
			 for (int i=0;i<numColumnas;i++){
				  registro.put(datoscol[i][0],null);
			  }
	   }
	   else {
		     String clave,tipo;
		     Object obj;
			 for (int i=0;i<numColumnas;i++){
				 clave=datoscol[i][0];
				 tipo=datoscol[i][1];
				 if (tipo.equals("java.lang.String"))
					 obj=rs.getString(clave);
				 else
				    obj=rs.getObject(clave);
				  registro.put(clave,obj);
			  }
	   }
   }
   
   public int getInt(String campo){
	   return ((Integer)registro.get(campo));
   }
   public String getString(String campo){
	   return ((String)registro.get(campo));
   }
   public Timestamp getFecha(String campo){
	   return ((Timestamp)registro.get(campo));
   }
   public boolean getBoolean(String campo){
	   return ((Boolean)registro.get(campo));
   }
   
   public void beforeFirst() throws SQLException {
	  rs.beforeFirst();
	  leerRegistro();
   }
   
   public void first() throws SQLException {
	  rs.first();
	  leerRegistro();
   }
   
   public void last() throws SQLException {
	  rs.last();
	  leerRegistro();
   }
   
   public boolean next() throws SQLException {
	  boolean salida;
	  salida=rs.next();
	  leerRegistro();
	  return salida;
   }
   
   public boolean previous()  throws SQLException {
	   boolean salida;
	   salida= rs.previous();
	   leerRegistro();
	 return salida;
   }
   
   public void move(int pos)  throws SQLException {
	  rs.absolute(pos);
	  leerRegistro();
   }
     
   public Object getColumn(int n) throws SQLException {
	  if(metadata.getColumnClassName(n).equals("java.lang.String"))
		 return rs.getString(n);
	  else
		 return rs.getObject(n);
   }
   
   public String registro() {
	  StringBuffer buf = new StringBuffer();
	  try {
		 for(int i=1;i <= numColumnas ;i++) {
			String s = rs.getString(i);
			if(rs.wasNull()) {
			   s = "";
			}
			buf.append(s).append('|');
		 }
	  } catch(Exception e) {
		 System.err.println(e.getMessage());
	  }
	  return buf.toString();
   }
   
   public String[] registros() {
	  try {
		 String[] todos = new String[this.recordsCount()];
		 beforeFirst();
		 int i=0;
		 while(next()) {
			todos[i++] = registro();
		 }
		 return todos;
	  } catch(Exception exc) {
		  Global.log.severe("ERROR al generar tabla de registros de la tabla " + tabla + "\n" +
					 exc.getMessage());
		 return null;
	  }
   }
   
   public int SQL(String sql) throws SQLException {
		 Statement stmt = conexion.createStatement();
		 return stmt.executeUpdate(sql);
   }
   
   public int SQL(String patron, Object[] args) throws SQLException {
	  String sql = java.text.MessageFormat.format(patron, args);
	  return SQL(sql);
   }
   
   
   
}
