====== Non-trigger Functions ====== These functions are called by the UI or manitou-mdx ===== trash_msg ===== CREATE OR REPLACE FUNCTION trash_msg(in_mail_id integer, in_op integer) RETURNS integer AS $$ DECLARE new_status int; BEGIN UPDATE mail SET status=status|16,operator=in_op WHERE mail_id=in_mail_id; SELECT INTO new_status status FROM mail WHERE mail_id=in_mail_id; RETURN new_status; END; $$ LANGUAGE 'plpgsql'; ===== trash_msg_set ===== CREATE OR REPLACE FUNCTION trash_msg_set(in_array_mail_id int[], in_op int) RETU RNS int AS $$ DECLARE cnt int; BEGIN UPDATE mail SET status=status|16, operator=in_op WHERE mail_id=any(in_array_mail_id); GET DIAGNOSTICS cnt=ROW_COUNT; return cnt; END; $$ LANGUAGE 'plpgsql'; ===== untrash_msg ===== CREATE OR REPLACE FUNCTION untrash_msg(in_mail_id int, in_op int) RETURNS int AS $$ DECLARE new_status int; BEGIN UPDATE mail SET status=status&(~16),operator=in_op WHERE mail_id=in_mail_id; SELECT INTO new_status status FROM mail WHERE mail_id=in_mail_id; RETURN new_status; END; $$ LANGUAGE 'plpgsql'; ===== delete_msg ===== CREATE OR REPLACE FUNCTION delete_msg(integer) RETURNS integer AS $$ DECLARE id ALIAS FOR $1; attch RECORD; cnt integer; o oid; BEGIN DELETE FROM notes WHERE mail_id=id; DELETE FROM mail_addresses WHERE mail_id=id; DELETE FROM header WHERE mail_id=id; DELETE FROM body WHERE mail_id=id; DELETE FROM mail_tags WHERE mail_id=id; FOR attch IN SELECT a.attachment_id,c.content,c.fingerprint FROM attachments a, attachment_contents c WHERE a.mail_id=id AND c.attachment_id=a.attachment_id LOOP cnt=0; IF attch.fingerprint IS NOT NULL THEN -- check if that content is shared with another message's attachment SELECT count(*) INTO cnt FROM attachment_contents WHERE fingerprint=attch.fingerprint AND attachment_id!=attch.attachment_id; END IF; IF (cnt=0) THEN PERFORM lo_unlink(attch.content); END IF; DELETE FROM attachment_contents WHERE attachment_id=attch.attachment_id; END LOOP; DELETE FROM attachments WHERE mail_id=id; UPDATE mail SET in_reply_to=NULL WHERE in_reply_to=id; SELECT mail_text INTO o FROM raw_mail WHERE mail_id=id; IF FOUND THEN PERFORM lo_unlink(o); DELETE FROM raw_mail WHERE mail_id=id; END IF; DELETE FROM mail WHERE mail_id=id; IF (FOUND) THEN RETURN 1; ELSE RETURN 0; END IF; END; $$ LANGUAGE 'plpgsql'; ===== delete_msg_set ===== CREATE OR REPLACE FUNCTION delete_msg_set(in_array_mail_id int[]) RETURNS int AS $$ DECLARE cnt int; BEGIN cnt:=0; FOR idx IN array_lower(in_array_mail_id,1)..array_upper(in_array_mail_id,1) LOOP cnt:=cnt + delete_msg(in_array_mail_id[idx]); END LOOP; RETURN cnt; END; $$ LANGUAGE 'plpgsql'; ====== Trigger Functions ====== The purpose of these functions is to maintain the contents of the ''mail_status'' table, which caches the status of current messages (current=not yet processed) ===== insert_mail ===== CREATE OR REPLACE FUNCTION insert_mail() RETURNS TRIGGER AS $$ BEGIN IF NEW.status&(256+32+16)=0 THEN -- The message is not yet sent, archived, or trashed INSERT INTO mail_status(mail_id,status) VALUES(new.mail_id,new.status); END IF; RETURN new; END; $$ LANGUAGE 'plpgsql'; ===== update_mail ===== CREATE OR REPLACE FUNCTION update_mail() RETURNS TRIGGER AS $$ DECLARE rc int4; BEGIN IF new.status!=old.status THEN IF NEW.status&(256+32+16)=0 THEN -- The message is not yet sent, archived, or trashed UPDATE mail_status SET status = new.status WHERE mail_id = new.mail_id; GET DIAGNOSTICS rc = ROW_COUNT; if rc=0 THEN INSERT INTO mail_status(mail_id,status) VALUES(new.mail_id,new.status); END IF; ELSE -- The mail has been "processed" DELETE FROM mail_status WHERE mail_id = new.mail_id; END IF; END IF; RETURN new; END; $$ LANGUAGE 'plpgsql'; ===== delete_mail ===== CREATE OR REPLACE FUNCTION delete_mail() RETURNS TRIGGER AS $$ BEGIN DELETE FROM mail_status WHERE mail_id=OLD.mail_id; RETURN old; END; $$ LANGUAGE 'plpgsql'; ====== Trigger declarations ====== CREATE TRIGGER update_mail AFTER UPDATE ON mail FOR EACH ROW EXECUTE PROCEDURE update_mail(); CREATE TRIGGER insert_mail AFTER INSERT ON mail FOR EACH ROW EXECUTE PROCEDURE insert_mail(); CREATE TRIGGER delete_mail AFTER DELETE ON mail FOR EACH ROW EXECUTE PROCEDURE delete_mail();