Hola que a todos mis lectores pues ahora tengo un nuevo trabajo y por lo tanto algo nuevo que hacer ahora lo que tengo que hacer es levantar un clúster usando LVS+Mysql Cluster+Cluster suite y por ahora me estoy “peleando” con la base de datos, se supone que solo es cuestión de migrar las tablas… pues bien aquí vamos a tener problemas primero que nada debemos de conocer son las desventajas de usar mysql-cluster una vez que las conocemos procedamos a continuar con el trabajo.
Primero que nada sabemos que las llaves foráneas no son permitidas en el engine NDB para eso tenemos que forzarlas con triggers podemos hacer los trigers a manita (si es que no tenemos muchas llaves) pero que pasa cuando tenemos muchas llaves??? Por eso mismo me he dado a la tarea de crear un programa para que escriba los triggers y aqui se los dejo Saludos cualquier duda estoy a sus ordenes :D

Nota: debes de tener el archivo .sql solamente con las llaves que arroja el mysqldump en el que se va a basar el programa por ejemplo:

Nota: Necesitas crear esta tabla para ke funcione las referencias:
CREATE TABLE error_msg (error_msg VARCHAR(32) NOT NULL PRIMARY KEY)Engine=ndbcluster;

—————————-ARCHIVO EJEMPLO DE MYSQLDUMP—————————-
– Filtros para la tabla `admin_agente_zona`
ALTER TABLE `admin_agente`
ADD CONSTRAINT `agente_agente` FOREIGN KEY (`id_agente`) REFERENCES `admin_` (`id_agente`),
ADD CONSTRAINT `agente_zona_` FOREIGN KEY (`id_zona`) REFERENCES `admin_zonas` (`id_zona`);
– Filtros para la tabla `admin_`
ALTER TABLE `admin_compania`
ADD CONSTRAINT `admin_compania_db` FOREIGN KEY (`postgis_db`) REFERENCES `admin_db_postgis` (`postgis_db`),
ADD CONSTRAINT `compania_Requiere_ FOREIGN KEY (`id_agente`) REFERENCES `admin_agente` (`id_agente`),
ADD CONSTRAINT `compania_Requiere_` FOREIGN KEY (`id_compania_padre`) REFERENCES `admin_compania` (`id_compania`),
ADD CONSTRAINT `compania_Requiere_` FOREIGN KEY (`id_tipo_cia`) REFERENCES `admin_tipo_compania` (`id_tipo_cia`);
– Filtros para la tabla `admin_empresa`
ALTER TABLE `admin_empresa`
ADD CONSTRAINT `admin_empresa_ibfk_1` FOREIGN KEY (`id_compania`) REFERENCES `admin_compania` (`id_compania`),
ADD CONSTRAINT `admin_empresa_ibfk_3` FOREIGN KEY (`id_tipo_empresa`) REFERENCES `admin_tipo_empresa` (`id_tipo_empresa`);
—————————————————————————————————————————————————————————
Clase: creadordetrigers.java 

package cradordetrigers;

package cradordetrigers;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 *
 * @author kloneton
 */
public class Main {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        {
            try {
                //se abre el archivo
                File f = new File("constraints.txt");
                BufferedReader entrada = new BufferedReader(new FileReader(f));
                // creando patrones para saber que linea procesaremos
                String lineaTabla = "";
                List lista = new ArrayList();
                //leer el archivo completo
                System.out.println("DELIMITER $$");
                int contador = 0;
                while (entrada.ready()) {

                    String texto = entrada.readLine();
                    if (texto.contains("ALTER TABLE")) {
                        lineaTabla = texto;
                        contador++;
                    } else if (texto.contains("ADD CONSTRAINT")) {
                        lista.add(texto);
                    } else if (texto.contains("Filtros")) {
                        //dando output al triger mofique esta linea en caso de querer escrivir en un archivo
                        System.out.println(creaTriger(lista, lineaTabla));
                        lista.clear();
                    }

                }
                System.out.println("DELIMITER  ;");
                System.out.println(contador);
            } catch (IOException ex) {
                System.out.println("Error al leer archivo");
                ex.printStackTrace();
            }
        }
    }

    public static String creaTriger(List lista, String lineatabla) {
        //primer expresion regular para separar ALTER TABLE lo que utilizaremos aqui sera el nombre de nuestra PK
        Pattern patronTabla = Pattern.compile("(\\w+) (\\w+) `(.+)`");
        //asignando expresion a un matcher para separar la palabara
        Matcher matPK = patronTabla.matcher(lineatabla);
        if (matPK.find()) {
            // linea de aqui arriba busca la exspresion regular
            //separando el nombre de la tabla que llevara los PK
            String tabla_PK = matPK.group(3);
            String tabla_FK = "";
            String anidacion = "";
            //segunda expresion regular para separar los miembros que nos serviran de referencia
            Pattern patronFK = Pattern.compile("(.+FOREIGN KEY)\\p{Blank}(\\(.+\\))\\p{Blank}REFERENCES\\p{Blank}\\`(.+)\\`\\p{Blank}(.+)[\\,\\;]$");
            //variables, variables... y mas variables inicializadas para que no marque nullpointerexeption
            String trigger = "";
            String campo_PK = "";
            String campo_FK = "";
            String prefijoIf = "IF ";
            int contador = 0;
            //iterando cada una de las lineas para asi generar el output
            for (Iterator it = lista.iterator(); it.hasNext();) {
                String linea = it.next();
                //asignando al matcher el patron para separar la linea que contiene la llave
                Matcher matFK = patronFK.matcher(linea);
                //buscando la exprecion regular
                matFK.find();
                //separando los miembros y quitando comillas y parentesis
                tabla_FK = matFK.group(3);
                campo_PK = matFK.group(2).replaceAll("[\\(\\)\\`]", "");
                campo_FK = matFK.group(4).replaceAll("[\\(\\)\\`]", "");
                //vsi tiene mas de una llave este for nos ayudara a separarlos y asi crear un solo trigger
                if (campo_PK.contains(",") && campo_FK.contains(",")) {
                    String camposPK[] = campo_PK.split(",");
                    String camposFK[] = campo_FK.split(",");
                    campo_PK = "";
                    campo_FK = "";
                    for (int i = 0; i < camposPK.length; i++) {
                        campo_PK += " alias." + camposPK[i].trim() + " = new." + camposFK[i].trim();
                        if (i < (camposFK.length - 1)) {
                            campo_PK += "  AND  ";
                        }
                    }

                } else {
                    campo_PK = "alias." + campo_PK.trim() + " = ";
                    campo_FK = "new." + campo_FK.trim();
                }
                //construyendo el trigger agregando if o else en caso de tener mas de una llave
                prefijoIf = (0 == contador++) ? "\tIF" : "\tELSEIF ";
                anidacion += prefijoIf + "(SELECT COUNT(*) FROM " + tabla_FK + " alias WHERE " + campo_PK + " " + campo_FK + ")=0" + " \n" +
                        " \tTHEN" + " \n" +
                        " \tINSERT error_msg VALUES ('FK_INSERT_" + tabla_PK + "_" + tabla_FK + " Key Violated');" + " \n";

            }
            //dando salida a los mensajes de error que se insertaran en la tabla ya mencionada
            System.out.println(" INSERT INTO error_msg values('FK_INSERT_" + tabla_PK + "_" + tabla_FK + " Key Violated')$");
            System.out.println(" INSERT INTO error_msg values('FK_UPDATE_" + tabla_PK + "_" + tabla_FK + " Key Violated')$");
            //estructuta estandar del triger la variable anidacion es el producto en caso de tener mas de una PK
            trigger = "" +
                    " CREATE TRIGGER FK_INSERT_" + tabla_PK + "_" + tabla_FK + " \n" +
                    "  BEFORE INSERT" + " \n" +
                    " \tON  " + tabla_PK + " \n" +
                    " \tFOR EACH ROW" + " \n" +
                    " \tBEGIN" + " \n" + anidacion +
                    " \tEND IF;" + " \n" +
                    " END;$$";
            //remplazando valores para hacer el Before Update
            String trigTemp = trigger;
            trigTemp = trigTemp.replace("new.", "old.");
            trigTemp = trigTemp.replaceAll("FK_INSERT", "FK_UPDATE");
            trigTemp = trigTemp.replaceAll("BEFORE INSERT", "BEFORE UPDATE");
            trigger += "\n" + trigTemp;

            return trigger;
        } else {
            return "";
        }
    }
}
Advertisement