Qualche tempo fa, ho avuto necessità di eseguire uno script esterno legato ad un trigger di PostgreSql.
All’epoca, l’unica soluzione che ho trovato è stata di creare una funzione in C che richiamasse lo script con i dovuti parametri.
Questo il codice:
[c]
#include
#include
#include “postgres.h”
#include
#include “fmgr.h”
#include “utils/builtins.h”
#define _textout(str) DatumGetPointer(DirectFunctionCall1(textout, PointerGetDatum(str)))
PG_FUNCTION_INFO_V1(esegui);
Datum esegui(PG_FUNCTION_ARGS);
Datum esegui(PG_FUNCTION_ARGS){
int pid;
char *path, *cmd, *host, *user, *pwd, *param; //Parametri della funzione
path = _textout(PG_GETARG_TEXT_P(0));
cmd = _textout(PG_GETARG_TEXT_P(1));
host = _textout(PG_GETARG_TEXT_P(2));
user = _textout(PG_GETARG_TEXT_P(3));
pwd = _textout(PG_GETARG_TEXT_P(4));
param = _textout(PG_GETARG_TEXT_P(5));
// Eseguo un fork per evitare di rallentare le operazioni sul database
switch(pid=fork()){
case -1: //Errore. Non posso eseguire il fork.
exit(-1);
case 0 : //Fork riuscita. Eseguo il codice “figlio”
execl(path, cmd, host, user, pwd, param,0); // Questo e’ il codice “figlio”
exit(1);
default:
return pid;
exit(1);
}
}
[/c]
Per utilizzare questa funzione con postgres, sono necessari pochi semplici passi:
Per prima cosa compiliamo la nostra funzione c (nel mio caso il file era: execcmdrouter.c).
gcc -I/usr/include/postgresql/server/ -shared execcmdrouter.c -o execcmdrouter.so
Copiamo l’oggetto ottenuto in “casa” di postgres e attribuiamogliene la proprietà 😉
cp execcmdrouter.so /var/lib/postgres/
chown postgres.postgres /var/lib/postgres/execcmdrouter.so
Quindi creiamo la funzione in postgres:
CREATE FUNCTION esegui(text,text,text,text,text,text) RETURNS INTEGER
AS '/var/lib/postgres/execcmdrouter.so' LANGUAGE C;
Fatto.
Spero possa a essere utile a qualcuno.