/* 
* 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.io.*;
import java.sql.*;
import java.util.*;
import java.util.logging.Level;
import servidor.Configuracion;
import servidor.comunicaciones.GestorColas;
import servidor.datos.base.*;
import servidor.utiles.*;

public class BaseDatos implements InterfacesAteneo.IBaseDatos {

    public Connection conexion;
    Connection conexionMaster;
    static BaseDatos yo = null;
    final String usuario = "ServidorAteneo";
    public static String pathLogBd = "BDLog.bin";
    public String pathAteneo;
    //private String pathAteneoLog;
    public boolean recuperacionActivada = false;
    public int errorSqlServer = 0;
    private String textoExcepcionBD = "";
    public static final int ERROR_ACCESO_FICHERO = 1;
    public static final int ERROR_CONEXION = 2;
    public static final int ERROR_NO_CONTROLADO = 9;
    private final ArrayList<ITablaReactivable> tablasAbiertas = new ArrayList<>();
    private boolean reconectandoAhora = false;
    String sqlExpress = "";

    public static BaseDatos bd() {
        if (yo == null) {
            yo = new BaseDatos();
            if (!yo.abrir()) {
                yo = null;
            }
        }
        return yo;
    }

    protected BaseDatos() {
    }

    public Connection getConnection() {
        return conexion;
    }

    public boolean abrir() {
        if (Configuracion.getConfiguracion().SQLExpress) {
            sqlExpress = ";instance=" + Configuracion.getConfiguracion().SQLInstanceName;
        }
        abrirBD();
        return conexion != null;
    }

    boolean abrirExterno = false;

    public boolean abrirSiCerrada() {
        if (conexion == null) {
            return abrir();
        }
        abrirExterno = true;
        return true;
    }

    public void cerrar() {
        try {
            conexion.close();
            yo = null;
        } catch (Exception e) {
            servidor.ServidorMain.log.warning("Error al cerrar la Base de Datos");
        }
    }

    public void registrarTabla(ITablaReactivable tabla) {
        if (!tablasAbiertas.contains(tabla)) {
            tablasAbiertas.add(tabla);
        }
    }

    Connection abrirBD() {
        // Primero cargamos el driver JDBC
        try {
            Class.forName("net.sourceforge.jtds.jdbc.Driver");
        } catch (java.lang.ClassNotFoundException e) {
            System.err.println("ClassNotFoundException: " + e.getMessage());
            return null;
        }
        // ahora intentamos la conexion
        Connection con = abrirConPasswordNormal(false);
        if (con == null) {
            con = abrirConPasswordAlternativa();
        }
        conexion = con;
        if (con != null) {
            extraePathBaseDatos();
            if (!reejecutaTransacciones()) {
                javax.swing.JOptionPane.showMessageDialog(null, "Hay datos NO CONSOLIDADOS en la base de datos\n"
                        + "Si todavía quiere continuar renombre el fichero 'BdLog.bin' y vuelva a ejecutar el servidor");
                Global.main.cerrarAplicacionSinEsperar();
            }
        }
        return con;
    }

    void extraePathBaseDatos() {
        try {
            Statement stmt = conexion.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
            if (stmt.execute("EXEC sp_helpdb '" + Configuracion.getConfiguracion().BaseDatosAte + "';")) {
                stmt.getMoreResults();
                ResultSet rs = stmt.getResultSet();
                rs.next();
                pathAteneo = rs.getString("filename").trim();
                //rs.next();
                //pathAteneoLog = rs.getString("filename").trim();
                stmt.close();
            }
        } catch (Exception exc) {
            //TODO ....
        }
    }

    public boolean reabrir() {
        conexion = abrirConPasswordNormal(true);
        return (conexion != null);
    }

    String password() {
        StringBuilder sb = new StringBuilder(usuario.substring(8));
        Global.passwordServidorSql = sb.reverse().toString();
        return Global.passwordServidorSql;
    }

    public String resolverNombreServidorSql() {
        String hostSql = servidor.Configuracion.getConfiguracion().servidorSql;
        if (hostSql.equalsIgnoreCase("localhost")) {
            try {
                java.net.InetAddress ie = java.net.InetAddress.getLocalHost();
                hostSql = ie.getHostName();
            } catch (Exception exc) {
                System.err.println(exc.getMessage());
            }
        }
        return hostSql;
    }

    public String nombreServidorSqlParaScript() {
        String hostSql = resolverNombreServidorSql();
        if (Configuracion.getConfiguracion().SQLExpress) {
            return hostSql + "\\" + Configuracion.getConfiguracion().SQLInstanceName;
        }
        return hostSql;
    }

    Connection abrirTablaMaster() {
        String hostSql = resolverNombreServidorSql();
        String baseAte = Configuracion.getConfiguracion().BaseDatosAte;       
        String url = "jdbc:jtds:sqlserver://" + hostSql + "/master" 
                + sqlExpress + ";user=" + usuario + " ;password=" + password();
        
        try {
            Connection con = DriverManager.getConnection(url);
            conexion = con;
            return con;
        } catch (Exception exc) {
            return null;
        }
    }

    void cerrarTablaMaster() {
        try {
            if (conexionMaster != null) {
                conexionMaster.close();
            }
        } catch (Exception exc) {
        }
    }

    Connection abrirConPasswordNormal(boolean reabriendo) {
        String hostSql = resolverNombreServidorSql();
        String baseAte = Configuracion.getConfiguracion().BaseDatosAte;

        String url = "jdbc:jtds:sqlserver://" + hostSql + "/" + baseAte
                + sqlExpress + ";user=" + usuario + " ;password=" + password();
        
        if (abrirExterno) {
            //System.out.println(url);
        }
        Connection con = null;
        try {
            con = DriverManager.getConnection(url);
            return con;
        } catch (SQLException e) {
            String mensaje = e.getMessage();
            if (mensaje.startsWith("No se puede abrir la base de datos solicitada en el inicio de sesión 'ateneo'")) {
                System.out.println("Reiniciando SQL Server...");
                EjecutarExterno.reiniciarSqlserver(true);
                try {
                    con = DriverManager.getConnection(url);
                    return con;
                } catch (SQLException ex) {
                    servidor.ServidorMain.log.log(Level.SEVERE, "SQLException {0}", ex.getMessage());
                    javax.swing.JOptionPane.showMessageDialog(null, "Se conectó con SqlServer pero no se puede abrir la base de datos 'Ateneo'.\n"
                            + "Compruebe que no hay otro servidor ATENEO corriendo contra la misma base de datos");
                    Global.main.cerrarAplicacionSinEsperar();
                }
            }
            if (mensaje.startsWith("Error de inicio de sesión") || mensaje.startsWith("Login failed")) {
                return null;
            }
            if (!reabriendo) {
                servidor.ServidorMain.log.log(Level.SEVERE, "SQLException {0}", e.getMessage());
                javax.swing.JOptionPane.showMessageDialog(null, "No se puede conectar con SQLServer. La aplicación no puede continuar");
                Global.main.cerrarAplicacionSinEsperar();
            }
        }
        return con;
    }

    Connection abrirConPasswordAlternativa() {
        String hostSql = resolverNombreServidorSql();
        String baseAte = Configuracion.getConfiguracion().BaseDatosAte;
        String url = "jdbc:jtds:sqlserver://" + hostSql + "/" + baseAte
                + sqlExpress + ";user=" + usuario + " ;password=xxx";
        Connection con;
        try {
            con = DriverManager.getConnection(url);
            CallableStatement stmt = con.prepareCall("{call sp_password(?,?)}");
            stmt.setString(1, "xxx");
            stmt.setString(2, password());
            stmt.execute();
            con.close();
            con = abrirConPasswordNormal(false);
            return con;
        } catch (SQLException e) {
            if (e.getMessage().startsWith("Error de inicio de sesión")) {
                String msg = "SERVIDOR ATENEO NO PUEDE CONECTAR CON LA BASE DE DATOS\n"
                        + "El usuario '" + usuario + "' no existe o no tiene la password necesaria.\n"
                        + "Consulte la documentación para solucionar este problema";
                javax.swing.JOptionPane.showMessageDialog(null, msg, "ERROR DE ACCESO A LA BD.", javax.swing.JOptionPane.ERROR_MESSAGE);
                servidor.ServidorMain.log.severe("Error en usuario " + usuario);
                System.exit(-1);
                return null;
            }
        }
        return null;
    }

    public void MoverTabla(String Origen, String Destino, String listaCampos) {
        MoverTabla(Origen, Destino, listaCampos, "");
    }

    public void MoverTabla(String Origen, String Destino, String listaCampos, String condicion) {
        try {
            Statement stmt = conexion.createStatement();
            String comando = "INSERT INTO " + Destino + " (" + listaCampos + ")"
                    + " SELECT " + listaCampos + " FROM " + Origen;
            if (!condicion.equals("")) {
                comando = comando + " WHERE " + condicion;
            }
            stmt.executeUpdate(comando);
            stmt.close();
        } catch (Exception exc) {
            servidor.ServidorMain.log.log(Level.WARNING, "ERROR en ''MoverTabla'' copiando de {0} a {1}:\n{2}", new Object[]{Origen, Destino, exc.getMessage()});
        }
    }

    public void borrarTabla(String tabla) {
        borrarTabla(tabla, "");
    }

    public void depurarTablaCandidatos() {
        try {
            Statement stmt = conexion.createStatement();
            String comando1 = "Update Candidatos Set Estado = 'I' WHERE Estado IN('F','S','D','A') AND DATEDIFF(MINUTE, HoraCalculada2,HoraAtendido) >  200";
            stmt.executeUpdate(comando1);
            comando1 = "Update AccionesHoy Set TiempoLibre = 0  where TiempoLibre  < 0 ";
            stmt.executeUpdate(comando1);
            comando1 = "Update AccionesHoy Set TiempoOcupado = 0  where TiempoOcupado  < 0 ";
            stmt.executeUpdate(comando1);
            comando1 = "Update AccionesHoy Set TiempoDescanso = 0  where TiempoDescanso < 0 ";
            stmt.executeUpdate(comando1);
            comando1 = "Update AccionesHoy Set TiempoLibre = 0  where TiempoLibre  > 57000 ";
            stmt.executeUpdate(comando1);
            comando1 = "Update AccionesHoy Set TiempoOcupado = 0  where TiempoOcupado  > 57000 ";
            stmt.executeUpdate(comando1);
            comando1 = "Update AccionesHoy Set TiempoDescanso = 0  where TiempoDescanso > 57000 ";
            stmt.executeUpdate(comando1);

            stmt.close();
        } catch (Exception exc) {
            servidor.ServidorMain.log.log(Level.WARNING, "ERROR depurarTablaCadidatos\n{0}", exc.getMessage());
        }
    }

    public void borrarTabla(String tabla, String condicion) {
        try {
            Statement stmt = conexion.createStatement();
            String comando = "DELETE FROM " + tabla;
            if (!condicion.equals("")) {
                comando = comando + " WHERE " + condicion;
            }
            stmt.executeUpdate(comando);
            stmt.close();
        } catch (Exception exc) {
            servidor.ServidorMain.log.log(Level.WARNING, "ERROR borrando tabla {0}\n{1}", new Object[]{tabla, exc.getMessage()});
        }
    }

    public void registrarTareaPlanificada(String codigo, String parametros, String descripcion, java.util.Date fecha) {
        String orden = java.text.MessageFormat.format("INSERT INTO Transmisiones (Tarea, parametros, descripcion, fecha, resultado) values"
                + "(''{0}'',''{1}'', ''{2}'', {3}, ''OK'')", new Object[]{codigo, parametros, descripcion, Fecha.formatoFechaSQL(fecha)});
        try {
            SQL(orden);
        } catch (Exception exc) {
            exc.printStackTrace();
        }
    }

    public boolean comprobarTransmisiones(String tarea, String param, java.util.Date fecha) {
        String filtro = java.text.MessageFormat.format("Tarea =''{0}'' and  parametros=''{1}'' and resultado=''OK'' and"
                + " fecha > {2}", new Object[]{tarea, param, Fecha.formatoFechaSQL(fecha)});
        try {
            Statement stmt = conexion.createStatement();
            ResultSet rs = stmt.executeQuery("Select Count(*) As Total from Transmisiones WHERE " + filtro);
            rs.next();
            // TODO Comprobar esto si Tabla vacia...
            int cuenta = rs.getInt(1);
            return cuenta > 0;
        } catch (SQLException ex) {
            ex.printStackTrace();
        }
        return false;
    }

    public boolean backup(java.util.concurrent.atomic.AtomicReference<Process> ref) {
        if (BaseDatos.bd().recuperacionActivada) {
            return false;
        }
        String pathBackupDatos = servidor.Configuracion.getConfiguracion().pathBackupDatos;
        if (pathBackupDatos == null || pathBackupDatos.trim().equals("")) {
            return false;
        }

        String orden = " \"BACKUP database ateneo TO DISK = '" + pathBackupDatos + "' WITH INIT \" ";
        Process proceso = null;
        try {
        // if (!servidor.Configuracion.getConfiguracion().SQLExpress) {
            //    proceso = Runtime.getRuntime().exec("C:\\MSSQL7\\binn\\osql.exe -U"
            //            + usuario + " -P" + password() + " -Q" + orden);
            // } else {
            //   String pOSQL = servidor.Configuracion.getConfiguracion().Osql;
            String pOSQL = "OSQL.EXE";
            String ateneo8 = servidor.Configuracion.getConfiguracion().servidorSql + "\\" + servidor.Configuracion.getConfiguracion().SQLInstanceName;
            proceso = Runtime.getRuntime().exec(pOSQL + " -U"
                    + usuario + " -P" + password() + " -S" + ateneo8 + " -Q" + orden);
            // }
            if (proceso != null) {
                ref.set(proceso);
                proceso.waitFor();
            }
            registrarTareaPlanificada("backup", Global.main.getTurno(), "backup base de datos", new java.util.Date());
        } catch (Exception exc) {
            servidor.ServidorMain.log.log(Level.WARNING, "ERROR al intentar BACKUP en  {0}", pathBackupDatos);
            servidor.ServidorMain.log.warning(exc.toString());
            // activarRecuperacion(exc);
            return false;
        }
        return true;
    }

    public void generarCitas() {
        ResultSet rs;
        GregorianCalendar cal = new GregorianCalendar();
        int hoy = cal.get(Calendar.DAY_OF_YEAR);
        boolean yaEjecutado = false;
        try {
            Statement stmt = conexion.createStatement();
            rs = stmt.executeQuery("SELECT * FROM GeneradorCitas");
            while (rs.next()) {
                Timestamp generacion = rs.getTimestamp("UltimaEjecucion");
                if (!rs.wasNull()) {
                    cal.setTime(generacion);
                    if (cal.get(Calendar.DAY_OF_YEAR) == hoy) {
                        yaEjecutado = true;
                        break;
                    }
                }
                String cola = rs.getString("Cola");
                TablaHuecos tablaHuecos = GestorColas.getGestor().tablaHuecos;
                cola = tablaHuecos.buscarRangoHuecos(cola);
                String turno = rs.getString("Turno");
                Timestamp horaInicio = Fecha.arreglarParaHoy(rs.getTimestamp("HoraInicio"));
                Timestamp horaFin = Fecha.arreglarParaHoy(rs.getTimestamp("HoraFin"));
                int minutos = rs.getInt("Duracion");
                int puestos = rs.getInt("Puestos");
                ArrayList<RegistroHuecos> generadas = tablaHuecos.generarHuecos(cola, turno, horaInicio, horaFin, minutos, puestos);
                tablaHuecos.incorporarHuecos(generadas);
            }
            rs.close();
            if (!yaEjecutado) {
                SQL("Update GeneradorCitas set UltimaEjecucion=GetDate()");
            }
        } catch (Exception exc) {
        }
    }
    
    // Procedimiento experimental de reacción ante fracasos del SQL Server
    java.util.Timer relojReconexion;

    public void activarRecuperacion(Exception exc) {
        if (recuperacionActivada) {
            return;
        }
        recuperacionActivada = true;
        conexionMaster = abrirTablaMaster();
        textoExcepcionBD = exc.getMessage();
        if (textoExcepcionBD.startsWith("El registro de la base de datos 'ateneo' no está disponible")
                || textoExcepcionBD.startsWith("Invalid state, the Connection object is closed")
                || textoExcepcionBD.startsWith("Error de E/S 1006(El volumen")) {
            errorSqlServer = BaseDatos.ERROR_ACCESO_FICHERO;
        } else if (textoExcepcionBD.startsWith("I/O Error: Connection reset by peer")) {
            errorSqlServer = BaseDatos.ERROR_CONEXION;
        } else {
            errorSqlServer = BaseDatos.ERROR_NO_CONTROLADO;
        }

        relojReconexion = new java.util.Timer();
        relojReconexion.schedule(new TimerTask() {

            @Override
            public void run() {
                if (reconectandoAhora) {
                    return;
                }
                reconectandoAhora = true;
                if (!reconectar()) {
                    reconectandoAhora = false;
                }
            }
        }, 20000, 20000);
        System.err.println("* SE HA ACTIVADO EL MODO DE EMERGENCIA DE SQLSERVER *");
        System.err.println("  (motivo:" + textoExcepcionBD + ")");
        servidor.comunicaciones.GestorColas.getGestor().notificarModoRecuperacion();
    }

    public boolean checkFiles() {
        int existe = 0;
        if (conexionMaster != null) {
            try {
                Statement stmt = conexionMaster.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
                if (stmt.execute("xp_fileexist '" + pathAteneo + "'")) {
                    ResultSet rs = stmt.getResultSet();
                    if (rs != null) {
                        rs.next();
                        existe = rs.getInt(1);
                    }
                }
                stmt.close();
            } catch (Exception exc) {
                exc.printStackTrace();
            }
        }
        return (existe > 0);
    }

    public boolean reconectar() {
        boolean sqlDisponible = false;
        switch (errorSqlServer) {
            case ERROR_CONEXION:
                sqlDisponible = recuperacionConexion();
                break;
            case ERROR_ACCESO_FICHERO:
                sqlDisponible = recuperacionFichero();
                break;
            case ERROR_NO_CONTROLADO:
                System.err.println("[Err.Recuperable: " + textoExcepcionBD + "]");
                sqlDisponible = recuperacionConexion();
                if (sqlDisponible) {
                    sqlDisponible = recuperacionFichero();
                }
                break;
        }

        if (sqlDisponible) {
            cerrarTablaMaster();
            System.out.println(" ** FIN DEL MODO DE EMERGENCIA DE SQLSERVER *");
            servidor.comunicaciones.GestorColas.getGestor().autoMensaje(servidor.comunicaciones.MensajeInterno.MSG_RECONECTAR_BD);
            return true;
        }
        return false;
    }

    boolean recuperacionFichero() {
        if (checkFiles()) {
            try {
                System.out.println(" ** INTENTANDO LA RECONEXIÓN DE LA BASE DE DATOS **");
                conexion.close();
                if (!EjecutarExterno.reiniciarSqlserver(false)) {
                    System.err.println(" No se ha podido reiniciar el servidor SQL");
                } else {
                    conexion = abrirConPasswordNormal(true);
                    if (conexion != null) {
                        return true;
                    }
                }
            } catch (Exception exc) {
                exc.printStackTrace();
            }
        }
        return false;
    }

    boolean recuperacionConexion() {
        conexion = abrirConPasswordNormal(true);
        return (conexion != null);
    }

    public void procesoRecuperacion() {
        relojReconexion.cancel();
        recuperacionActivada = false;
        if (reejecutaTransacciones()) {
            for (ITablaReactivable tablasAbierta : tablasAbiertas) {
                (tablasAbierta).preparaStmt();
            }
        }
    }

    boolean reejecutaTransacciones() {
        try {
            File file = new File(BaseDatos.pathLogBd);
            if (!file.exists()) {
                return true;
            }
            FileReader inStr = new FileReader(file);
            BufferedReader br = new BufferedReader(inStr);
            conexion.setAutoCommit(false);
            Statement stmt = null;
            int numLinea = 1;
            try {
                String sqlStr;
                stmt = conexion.createStatement();
                while ((sqlStr = br.readLine()) != null) {
                    stmt.executeUpdate(sqlStr);
                    numLinea++;
                }

                conexion.commit();
                stmt.close();
                System.out.println(" ** COMPLETADA LA RECUPERACIÓN DE DATOS DEL REGISTRO DE EMERGENCIA **");
            } catch (Exception exc) {
                conexion.rollback();
                servidor.ServidorMain.logException("Recuperacion de emergencia fallida. Error en linea " + numLinea, exc);
                System.err.println(" NO SE HAN PODIDO RECUPERAR LOS DATOS DEL REGISTRO DE EMERGENCIA ");
                System.err.println("Error en la linea " + numLinea);
                System.err.println("  ** CONSULTE CON EL ADMINISTRADOR DE SU OFICINA ** ");
                reconectandoAhora = false;
                return false;
            } finally {
                conexion.setAutoCommit(true);
                if (stmt != null) {
                    stmt.close();
                }
                br.close();
            }
            file.delete();

        } catch (Exception exc) {
            exc.printStackTrace();
        }
        reconectandoAhora = false;
        return true;
    }

    @Override
    public int SQL(String sql) throws SQLException {
        Statement stmt = conexion.createStatement();
        int n = stmt.executeUpdate(sql);
        stmt.close();
        return n;
    }

    public int SQL(String patron, Object[] args) throws SQLException {
        String sql = java.text.MessageFormat.format(patron, args);
        return SQL(sql);
    }

    public ResultSet abrirTabla(MemTabla tabla) {
        String select = tabla.select();
        try {
            Statement stmt = conexion.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
            registrarTabla(tabla);
            return stmt.executeQuery(select);
        } catch (SQLException ex) {
            activarRecuperacion(ex);
        }
        return null;
    }

    @Override
    public ResultSet abrirTabla(String select) {
        try {
            Statement stmt = conexion.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
            return stmt.executeQuery(select);
        } catch (SQLException ex) {
            System.err.println("No se pudo abrir la consulta:");
            System.err.println("  " + select);
        }
        return null;
    }

    @Override
    public ResultSet abrirTablaActualizable(String select) {
        try {
            Statement stmt = conexion.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
            return stmt.executeQuery(select);
        } catch (SQLException ex) {
            ex.printStackTrace();
        }
        return null;
    }

    @Override
    public int executeQuery(String select) {
        try {
            Statement stmt = conexion.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
            ResultSet rs = stmt.executeQuery(select);
            rs.first();
            int v = rs.getInt(1);
            rs.close();
            stmt.close();
            return v;
        } catch (SQLException ex) {
            ex.printStackTrace();
        }
        return -1;
    }

    public void ajustarMemoria() {
        if (BaseDatos.bd().recuperacionActivada) {
            return;
        }
        try {
            GregorianCalendar cal = new GregorianCalendar();
            int hora = cal.get(Calendar.HOUR_OF_DAY);
            if (hora > 1) {
                return;
            }
            System.out.println("Limpieza de momoria");
            Statement stm = conexion.createStatement();

            stm.execute("EXEC sys.sp_configure N'max server memory (MB)', N'256'");
            stm.execute("RECONFIGURE WITH OVERRIDE");
            Thread.sleep(25000);
            stm.execute("EXEC sys.sp_configure N'max server memory (MB)', N'1024'");
            stm.execute("RECONFIGURE WITH OVERRIDE");

            stm.close();
        } catch (Exception exc) {
            exc.printStackTrace();
        }
    }

    public void despertar() {
        try {
            if (BaseDatos.bd().recuperacionActivada) {
                return;
            }
            Statement stm = conexion.createStatement();
            ResultSet rs = stm.executeQuery("SELECT * FROM  [master].[dbo].[MSREPLICATION_OPTIONS]");
            rs.close();
            stm.close();
        } catch (Exception exc) {
        }
    }

}
