Jaime Casanova escribió:
> 2009/7/2 Alvaro Herrera <alvhe...@alvh.no-ip.org>:
> >
> > El supuesto listener.c es el responsable de enviar el email.
> 
> a todo esto, aun tienes ese codigo en algun lado?

Ese código no servía para nada (estaba incompleto y como además estaba
en C, no era muy práctico), así que escribí uno en Perl, adjunto.  Si
alguien quiere convertirlo en PHP, etc, bienvenido sea ...

-- 
Alvaro Herrera                        http://www.advogato.org/person/alvherre
"Porque francamente, si para saber manejarse a uno mismo hubiera que
rendir examen... ¿Quién es el machito que tendría carnet?"  (Mafalda)
#!/usr/bin/perl
#
# Programa ejemplo para un "listener" de PostgreSQL, que funciona como un
# daemon que está colgado esperando recibir notificaciones desde el servidor,
# y cuando las recibe, examina el estado de una tabla para enviar emails.
#
# NOTA: este programa es muy primitivo y debe ser considerado solamente un
# ejercicio académico con propósitos demostrativos.  Un programa de calidad de
# producción necesariamente debe ser al menos el doble de largo.

use warnings;
use strict;

use DBI;
use Net::SMTP;

my $dbh = DBI->connect("dbi:Pg:dbname=alvherre", '', '');

my $sth1 = $dbh->prepare('SELECT email_id, destinatario, subject, body
			    FROM emails_por_enviar');

# Antes de dormir, verifica si hay algo que hacer
determina_emails_por_enviar();

# Ahora entra en el ciclo infinito que queda esperando hasta que haya
# algo que hacer.
$dbh->do("LISTEN envia_email");
while (1) {
	my $rin = '';
	my $rout;
	my $nfound;
	# La orden "select" deja bloqueado al programa hasta que el servidor
	# nos indique que tiene alguna notificacion que enviarnos.
	vec($rin, $dbh->{pg_socket}, 1) = 1;
	$nfound = select($rout = $rin, undef, undef, undef);

	determina_emails_por_enviar();
}

# Examina la tabla de emails encolados, e invoca la rutina send_email para
# cada uno de ellos.  Luego, borra de la tabla los emails que fueron enviados.
sub determina_emails_por_enviar {
	my @ids;
	$dbh->begin_work();
	$dbh->do('SET TRANSACTION ISOLATION LEVEL SERIALIZABLE');
	$sth1->execute();
	while (my $h = $sth1->fetchrow_hashref) {
		send_email($h);
		# Guarda en un array el ID de cada email enviado.
		push @ids, $h->{email_id};
	}
	if ($#ids > 0) {
		# Esto parece extraño, pero el join/map lo único que hace es
		# poner un ? por cada elemento del array @ids.
		my $sth2 = $dbh->prepare(
			'DELETE FROM emails_por_enviar WHERE email_id IN ('.
			(join ",", (map { "?" } @ids)) . ')');
		$sth2->execute(@ids);
	}
	$dbh->commit;
}

# Hace el envío de email.
sub send_email {
	my $opts = shift;

	print "enviando email a " . $opts->{destinatario} . "\n";
	my $smtp = Net::SMTP->new('localhost');
	$smtp->mail($ENV{USER});
	$smtp->to($opts->{destinatario});
	$smtp->data;
	$smtp->datasend("Subject: " . $opts->{subject} . "\n");
	$smtp->datasend("\n");
	$smtp->datasend($opts->{body});
	$smtp->dataend;
	$smtp->quit;
}
--
TIP 2: puedes desuscribirte de todas las listas simultáneamente
    (envía "unregister TuDirecciónDeCorreo" a majord...@postgresql.org)

Responder a