Otra de las múltiples carencias de MySQL es que no tiene un sistema de dependencias entre objetos. Por ejemplo, un procedimiento almacenado que isnerta en una tabla, o lee de una vista, o una vista que lee de otras tablas o vistas, etc…
Te permite borrar o cambiar de nombre un objeto aun cuando está siendo referenciado desde otro sitio. Esto hay quien lo ve como una ventaja (es más cómodo siempre que sepas lo que estás haciendo). Pero para un proyecto medianamente grande y en el que trabajen varias personas se hace inmantenible.
Siempre queda la opción de hacer un programa que lea los ficheros fuente, y sepa encontrar ahí dónde se referencian otros objetos o ficheros fuente. He estado buscando en Internet algo hecho y solo he visto alguna cosa para ficheros .c y .h. Asi que he preparado este script como solución rápida. De momento solo busca en ficheros fuente de Perl y de procedimientos almacenados de MySQL.
Va dibujando un arbol de las llamadas entre unos y otros. Por ejemplo:
perl1.pl perl2.pl mysql1.sql mysql2.sql mysql4.sql mysql5.sql
en este caso el fichero perl1.pl llama a un programa Perl (perl2) y a 3 procedimientos almacenados (mysql1, mysql2 y mysql5), y mysql2 a su vez llama a mysql4
Los parámetros del programa son el fichero fuente a partir del cual se empieza a buscar, y la lista de directorios en los que buscar, y se ejecuta desde el directorio que contiene a éstos. Ej:
--raiz/ |--perl/ |-- perl1.pl |-- perl2.pl |--mysql/ |-- mysql1.pl
En este caso se llamaría desde ‘raiz’, por ejemplo con:
dependencias.pl perl1.pl {perl,mysql}
Requiere el módulo File::Grep, que sirve para lo mismo que el comando grep. Es bastante incómodo de utilizar y probablemente habría sido mejor utilizar simplemente grep en un script de shell o de Perl.
El programa es fácilmente adaptable a otros lenguajes. Solo hay que especificar cómo se hacen las llamadas a otros scripts (do, call, system, …)
Se agradecen ampliaciones y correcciones.
#!/usr/bin/perl use File::Grep qw( fgrep ); die "Uso: dependencias.pl <archivo fuente inicial> {directorio1,directorio2}...\n\n" unless @ARGV == 2; my $directorios = $ARGV[1]; busca($ARGV[0], ""); sub busca { my $ocurrencia; my %matches; my $match_key; foreach $ocurrencia (fgrep { /(call|do).*\(/i } glob "$directorios/$_[0]") { %matches = %{${$ocurrencia}{'matches'}}; # matches es un hash que contiene las lineas encontradas foreach (sort keys %matches) { if ($matches{$_} =~ m/call\s+(.+)\(/i) { # llamadas a procedimientos almacenados MySQL print "$_[1]$1.sql\n"; busca("$1.sql", $_[1]." "); } elsif ($matches{$_} =~ m/do.*\'(.+)\'/i) { # llamadas a scripts Perl print "$_[1]$1\n"; busca("$1", $_[1]." "); } } } }
Deja un comentario