Método para validar erros em expressões regulares

Em um determinado momento, tive a necessidade de efetuar validações em expressões regulares inseridas pelo usuário em textbox.

Abaixo segue método que eu utilizei para esta validação:

function validaRegex($regex, $escapar=false)
	{
		if($escapar) $regex = str_replace('/', '/', addslashes($regex));
		$teste = null;
		ini_set('track_errors', 1);
		$teste = @preg_match("/{$regex}/", "<a href="http://$1" target="_blank">[LINK]</a>", $teste);
		$ret = @strip_tags($php_errormsg);
		ini_set('track_errors', 0);
		$r = explode(':', $ret);
		return ($ret) ? array(false, trim($r[1])) : Array(true);
	}

Para explicar o funcionamento:
A variável $teste  (sim, faltou criatividade) recebe o resultado do preg_match, sendo que este recebe no primeiro parametro o valor digitado pelo usuário e o segundo parametro pode ser qualquer porcaria que vier em mente, já que o que nos interessa é se o regex do usuário tem erro ou não

O retorno é um array, sendo que a posição [0] retorna True ou False, e, havendo erro  no regex, a posição [1] retorna a mensagem de erro do php

———————————————-
Posted Listening: “Lights Out – UFO”

Trabalhando com triggers (insert, update delete)

Eu utilizava um rotina em php para sincronizar duas tabelas, ela rodava via cron uma vez por hora, porém isso me gerava um certo incômodo, pois as mesmas mensuravam espaço em disco em disco de alguns servidores e as vezes precisava dos dados na hora.

Até que uma hora resolví deixar a preguiça de lado e fazer de uma forma decente, via trigger.

Deixo aqui compartilhado as trigger que criei, aonde podem ser utilizadas como exemplo para after insert, after update e after delete:

After Insert:

DELIMITER $$
CREATE DEFINER=CURRENT_USER TRIGGER sincroniza_backup AFTER INSERT ON tabela_origem
  FOR EACH ROW BEGIN
    INSERT INTO tabela_destino SET
	id 				= NEW.id_servidor,
	nome			= NEW.nome_servidor,
	particao		= NEW.particao,
	tamanho			= NEW.tamanho,
	ocupado			= NEW.ocupado,
	livre			= NEW.livre,
	percentualUso	= NEW.percentual_uso;
  END;
$$
DELIMITER ;

Aqui o parametro NEW, recebe os dados da row afetada pelo insert executado

Para after update:

DELIMITER $$
CREATE DEFINER=CURRENT_USER TRIGGER sincroniza_backup_update AFTER UPDATE ON tabela_origem
  FOR EACH ROW BEGIN
    UPDATE tabela_destino sb SET
	sb.nome			= NEW.nome_servidor,
	sb.ocupado		= NEW.ocupado,
	sb.livre			= NEW.livre,
	sb.percentualUso	= NEW.percentual_uso,
	sb.testeEmail	= NEW.teste_email
	WHERE sb.nome=NEW.nome_servidor AND sb.particao=NEW.particao;
  END;
$$
DELIMITER ;

Mais uma vez o parametro NEW recebe os dados da tabela de origem (as rows afetadas pelo update)

Esse é um pouco diferente, o after delete

DELIMITER $$
CREATE DEFINER=CURRENT_USER TRIGGER sincroniza_backup_delete AFTER DELETE ON servidor_backup
  FOR EACH ROW BEGIN
    DELETE FROM ServidorBackup WHERE
	nome=OLD.nome_servidor AND particao=OLD.particao;
  END;
$$
DELIMITER ;

Nesse caso o valor que as rows deletas continham vão pro OLD

Agora o bonus stage:
Para deletar uma trigger

DROP TRIGGER sincroniza_backup_update;

———————————————-
Posted Listening: “Schools Out – Alice Cooper”

Deletar registros com mais de 30 dias

Essa é básica, mas vejo muita gente se quebrando e fazendo códigos mirbolantes via script pra isso.

Para deletar qualquer registro com mais de 30 dias somente usando SQL (não esqueça de substituir o campo `date` pelo nome do campo que irá utilizar e `minha_tabela` pelo nome da tabela.

DELETE FROM `minha_tabela` WHERE `date` < DATE_SUB(NOW(), INTERVAL 30 DAY);

———————————————-
Posted Listening: “The Evil That Men Do – Iron Maiden”

Resolvendo problemas de travamento do thunderbird (em definitivo!)

Se você é que nem eu que recebe centenas de milhares de emails todos os dias, aliado a uma quantidade generosa de filtros pra organizar tudo, passa ou com cerveja já passou por situações de travamentos, aos quais as vezes são constantes.

Em minha maquina de trabalho (core I5 com 4Gb RAM) chegou a um ponto que o thunderbird passava 60% ou mais do dia travado, sendo que as vezes eu ra obrigado a apelar para o webmail 😛

Bom, graças ao meu grande colega totoro, esses problemas “se acabaram-se”, o programa (gratuito) thunderfix resolve esse problema na hora! E o bom é que não precisa ficar rodando ele sempre, faz mais de um mes que rodei e até agora nada de travar! =D

O funcionamento dele consiste basicamente em procurar todos os arquivos .msf do profile escolhido e apagar.

Link para download:

http://www.superdownloads.com.br/download/93/thunderfix/

———————————————-
Posted Listening: “El Dorado – Iron Maiden”

Function para retornar todos os IPs de um range

Esses tempos tive a necessidade de obter uma lista de todos os ips contidos em um range.

Se fossem somente ranges /24 seria muito fácil, porém para o sistema que eu estava desenvolvendo havia necessidade de escalabilidade, podendo ser inserido qualquer range como /16 /30 /28, etc.

Depois de procurar muito no oráculo google achei algo que se aproximava do que eu precisava, a classe net/ipv4 do PEAR, eu digo que se aproximava porque ela retorna o primeiro e o último IP de qualquer range, mas não a lista completa.

Com a classe ipv4 em mãos, resolví escrever a function abaixo que me retorna a lista completa:

function calculateIpRange($cidr) {
        $cidr = trim($cidr);
        if(!preg_match("/[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}/[0-9]{1,2}/", $cidr)){
                return Array(false, 'O IP deve estar no formato XXX.XXX.XXX.XXX/XX --> Exemplo 192.168.0.50/28');
        }
        if(!@include_once 'Net/IPv4.php')
        {
                return Array(false, 'Classe Net_IPv4 não está instalada --> http://pear.php.net/package/Net_IPv4/');
        }

        if(!is_callable('Net_IPv4', 'parseAddress'))
        {
                return Array(false, 'Metodo Net_IPv4::parseAddress inexistente');
        }
        $ip_calc = Net_IPv4::parseAddress($cidr);
        if($ip_calc->message)
        {
                return Array(False, $ip_calc->message);
        }

        $s = sprintf("%u",ip2long($ip_calc->network));
        $e = sprintf("%u",ip2long($ip_calc->broadcast));
        for($i=$s;$i<=$e;$i++){
                $r[] = long2ip($i);
        }
        return Array(
                true,
                'info' => Array(
                        'total' => sizeof($r),
                        'source'        => $cidr,
                        'network' => $ip_calc->network,
                        'broadcast' => $ip_calc->broadcast,
                        'netmask'       => $ip_calc->netmask
                ),
                'data' => $r
        );
}

NOTA: Este método necessita da classe net/ipv4 do pear instalada no servidor, o que pode ser realizado com o comando abaixo:

pear install Net_IPv4-1.3.4

Na dúvida, consulte seu provedor para instalação da mesma no servidor 😉

———————————————-
Posted Listening: “Starblind – Iron Maiden”

Visualizar todas as chaves estrangeiras (foreign keys) do banco de dados

SQL Pra listar todas as chaves estrangeiras criadas

select
CONSTRAINT_NAME as 'foreign_name',
concat(table_name, '.', column_name) as 'foreign _key',
concat(referenced_table_name, '.', referenced_column_name) as 'references'
from
information_schema.key_column_usage
where
referenced_table_name is not null;

OBS: Deve ter um jeito mais fácil, mas esse quebra bem o galho 😉

———————————————-
Posted Listening: “Hot for Teacher – Van Hallen”

Instalar Módulos PERL

Sempre que me deparava erros como o abaixo em um perl, quase chorava, agora graças ao totoro ficou bem simples!

Exemplo de erro:

Can’t locate FCGI.pm in @INC (@INC contains: /etc/perl /usr/lib64/perl5/site_perl/5.12.3/x86_64-linux /usr/lib64/perl5/site_perl/5.12.3 /usr/lib64/perl5/vendor_perl/5.12.3/x86_64-linux /usr/lib64/perl5/vendor_perl/5.12.3 /usr/lib64/perl5/site_perl /usr/lib64/perl5/vendor_perl /usr/lib64/perl5/5.12.3/x86_64-linux /usr/lib64/perl5/5.12.3 /usr/local/lib/site_perl .) at /usr/local/bin/fastcgi-wrapper.pl line 3.
BEGIN failed–compilation aborted at /usr/local/bin/fastcgi-wrapper.pl line 3

Solução:

perl -eshell -MCPAN
install FCGI

OBS: Case sensitive (sim, tive problema com isso :P)

———————————————-
Posted Listening:  “Back to Madness – Stratovarius”