Buenas a todos, tengo un problemilla medio feo...
Resulta que estoy tratando de crear una funcion para postgresql 8.1.4
que me permita eliminar archivos en un sistema Linux (uso SuSE Linux 9.2)
revise la documentacion, pero no entontre alguna funcion en plpgsql
que me lo permitiera (al menos lo unico que encontre fueron las funciones
pg_ls_dir,pg_read_file y pg_stat_file, que sirven para listar los archivos
de un directorio, leer el contenido de un archivo y mostrar info del archivo
respectivamente).
Asi que, como quiero si o si esa funcion, decidi implementar la mia :)
Para empezar algo sencillito nomas, asi que engendre esta cosa...
// File: muerefile.c
// Este archivo lo cree usando el usuario postgres de linux
// guardandolo en su directorio home (por cierto, no hay ningun problema con tener /home/postgres ???)
// y usando las librerias de postgres para despues poder usarlo como funcion extendida
#include "postgres.h"
#include "postgres_fe.h"
#include <string.h>
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
int removefile(text *namef)
{
int r;
//bool result;
int result;
errno = 0;
//r = remove("/home/postgres/algo.txt");
//r = remove((const char *) VARDATA(namef));
r = unlink((const char *) VARDATA(namef));
if( r == 0)
{
//result = true;
result = r;
}
else
{
//result = false;
result = errno;
}
return result;
// Repito: este programa es solo una pruebita nomas, no se ofendan por lo simple que es
}
compile con cc de esta manera:
cc -fpic -c -I /midir/hacia/postgres-8.1.4/src/include muerefile.c
cc -shared muerefile.so muerefile.o
Todo salio perfecto (claro, despues de varios problemas con ese bendito tipo de datos text)
ya tenia mi libreria muerefile.so
Luego entre a mi base de datos con una cuenta con provilegios para crear funciones (no postgres)
de esta manera : psql mibase -U miuser (! ... eso ya lo saben creo...)
y ejecute la siguiente instruccion:
CREATE FUNCTION removefile(text) RETURNS integer AS '/midir/hacia/muerefile.so','removefile' LANGUAGE C STRICT;
Dios mio, yo hice eso ??? (soy nuevo en pgsql... y en linux...)
Todo salio bien, entonces al probarlo, me salen estos problemas....
///// Problemas //////
1. Cuando intento eliminar un archivo, a veces lo elimina y aveces no, mejor dicho, CUANDO SE LE ANTOJA
Me eplico, creo un archivo algo.txt con algunos caracteres, desde mi cuenta postgres y utilizo:
select removefile('home/postgres/algo.txt');
removefile
------------
0
(1 row)
Por cierto, la funcion devolvera el resultado de la funcion unlink (0 si se realizo, -1 si fallo)
Ahora, cuando lo ejecuto nuevamente, la funcion me devuelve 2 (archivo no encontrado)
y no esta mal, puesto que acabo de eliminarlo en la llamada anterior. Pero el problema
surge aqui, cuando creo nuevamente el archivo algo.txt en la misma ubicacion y ejecuto la funcion.
no me devuelve 0 sino 2, pero el archivo si existe !!! , lo acabo de crear !!!
Desconcertado por esto, intente de todo, otorgar mas permisos (aunque ilogico puesto que la funcion
siempre me devuelve 2->'archivo no encontrado' y no 13->'permiso denegado')
y lo que me desconcerto mas es que sali de mi base de datos (comando \q :) )
ingrese nuevamente, ejecute la funcion, y me devolvio 0 !!!
Oh sorpresa, resulta que cada vez que la funcion devuelve 2 y el archivo existe, saliendo de la base
y volviendo a entrar la funcion elimina efectivamente el archivo y me devuleve 0
osea, como ya dije, cuando al parecer... se le antoja...
2. Cuando creo otros archivos e intento eliminarlos, sucede lo mismo, a algunos los elimina, y a otros no
a veces elimina un archivo, lo vuelvo a crear, me lo vuelve a eliminar, pero sucede muy a menudo, aunque
no siempre, que si retorna 2, se frego, porque ya no me elimina nada,,, pero insisto, no siempre.
La unica manera de asegurarme que un archivo se elimine es saliendo de mi base de datos, entrando
y llamando a la funcion (un logout y login por cada file que quiero eliminar... algo horrible verdad ???)
3. Lo mas alarmante: ejecuto un programa muy similar para eliminar archivos y me los elimina siempre;
la diferencia es que lo compilo con gcc (genero un ejecutable comun, independiente de postgres)
gcc -o muerefile.exe muerefile2.c (la diferencia es la ausencia de librerias pgsql y sus tipos de datos)
///////// Preguntas /////////
¿Porque sucede esto? ¿Es algun problema de Postgres, o de mi programa?
¿De alguna manera, funciones postgres 'repite simplemente' un valor devuelto anteriormente?
¿O lo que es peor, postgres guarda 'en cache' ese resultado y lo utiliza despues sin ejecutar realmente
la funcion 2 veces, al estilo web ?
¿Alguna otra solucion para eliminar archivos desde postgres?
__________________________________________________
Correo Yahoo!
Espacio para todos tus mensajes, antivirus y antispam ¡gratis!
Regístrate ya - http://correo.yahoo.es