Le module lo
ajoute un support des « Large
Objects » (aussi appelé LO ou BLOB). Il inclut le type de données
lo
et un trigger lo_manage
.
Ce module est considéré comme « trusted », ce qui signifie qu'il
peut être installé par des utilisateurs simples (sans attribut
SUPERUSER
) et qui ont l'attribut CREATE
sur la base de données courante.
Un des problèmes avec le pilote JDBC (mais cela affecte aussi le pilote ODBC) est que la spécification suppose que les références aux BLOB (Binary Large OBject) sont stockées dans une table et que, si une entrée est modifiée, le BLOB associé est supprimé de cette base.
En l'état actuel de PostgreSQL, ceci n'arrive pas. Les « Large Objects » sont traités comme des objets propres ; une entrée de table peut référencer un « Large Object » par son OID, mais plusieurs tables peuvent référencer le même OID. Donc, le système ne supprime pas un « Large Object » simplement parce que vous modifiez ou supprimez une entrée contenant un tel OID.
Ceci n'est pas un problème pour les applications spécifiques à PostgreSQL mais un code standard utilisant JDBC ou ODBC ne supprimera pas ces objets, ceci aboutissant à des « Large Objects » orphelins -- des objets qui ne sont référencés par personne et occupant de la place.
Le module lo
permet de corriger ceci en attachant un
trigger aux tables contenant des colonnes de référence des LO. Le trigger
fait essentiellement un lo_unlink
quand vous supprimez
ou modifiez une valeur référence un « Large Object ». Quand vous
utilisez ce trigger, vous supposez que, dans toute la base de données, il
n'existe qu'une seule référence d'un « Large Object » référencé
dans une colonne contrôlée par un trigger !
Le module fournit aussi un type de données lo
, qui n'est qu'un
domaine sur le type oid
. Il est utile pour différencier les
colonnes de la base qui contiennent des références d'objet de ceux qui
contiennent des OID sur d'autres choses. Vous n'avez pas besoin d'utiliser
le type lo
pour utiliser le trigger mais cela facilite le
travail pour garder la trace des colonnes de votre base qui représentent
des « Large Objects » que vous gérez avec le trigger. Une rumeur
dit aussi que le pilote ODBC a du mal si vous n'utilisez pas le type
lo
pour les colonnes BLOB.
Voici un exemple d'utilisation :
CREATE TABLE image (title TEXT, raster lo); CREATE TRIGGER t_raster BEFORE UPDATE OR DELETE ON image FOR EACH ROW EXECUTE FUNCTION lo_manage(raster);
Pour chaque colonne qui contiendra des références uniques aux « Large
Objects », créez un trigger BEFORE UPDATE OR
DELETE
trigger, et donnez le nom de la colonne comme argument du
trigger. Vous pouvez aussi restreindre le trigger pour ne s'exécuter que
sur les mises à jour de la colonne en utilisant BEFORE UPDATE
OF
nom_colonne
. Si
vous avez plusieurs colonnes lo
dans la même table, créez un
trigger séparé pour chacune en vous souvenant de donner un nom différent à
chaque trigger sur la même table.
Supprimer une table résultera quand même en des objets orphelins pour
tous les objets qu'elle contient, car le trigger n'est pas exécuté. Vous
pouvez éviter ceci en faisant précéder le DROP TABLE
avec DELETE FROM
.
table
TRUNCATE
présente le même danger.
Si vous avez déjà, ou suspectez avoir, des « Large Objects »
orphelins, voir le module vacuumlo (vacuumlo) pour vous aider à les nettoyer. Une bonne idée est
d'exécuter vacuumlo occasionnellement pour
s'assurer du ménage réalisé par le trigger
lo_manage
.
Quelques interfaces peuvent créer leur propres tables et n'ajouteront pas les triggers associés. De plus, les utilisateurs peuvent oublier de créer les triggers, ou ne pas savoir le faire.
Peter Mount <peter@retep.org.uk>