Skip to content

Commit de2ee18

Browse files
committed
Drop mail_status in favor of a partial index on the unarchived mail.
Initially the reason for mail_status is the simplicity and cross-dbms portability. But a partial index performs better that joining against plus maintaining mail_status, and porting to a different dbms is not a current goal. Installations that want to keep relying on mail_status for the compatiblity of their queries can have it as a view: CREATE VIEW mail_status AS select mail_id,status from mail where status&(256+32+16)=0; The partial index is on status&32=0 only, to simplify the logic. Messages that are trashed (16) or sent (256) tend to be archived, so it's okay, performance-wise, not to bother about trashed but not archived, or sent but not archived. As a consequence of dropping mail_status, the triggers on insert, update, delete on mail are dropped as well. Also create status_mask() to help with status bitmasks readability in code. Note: this commit does not touch manitou-mdx, but a previous commit fdf22c3 already carried the change (removing a join with mail_status) that should have landed in this commit.
1 parent 4be14a4 commit de2ee18

File tree

1 file changed

+24
-69
lines changed

1 file changed

+24
-69
lines changed

lib/Manitou/Schema.pm

Lines changed: 24 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -81,12 +81,6 @@ CREATE TABLE notes (
8181
);
8282
CREATE UNIQUE INDEX notes_idx ON notes(mail_id);
8383
84-
CREATE TABLE mail_status (
85-
mail_id int,
86-
status int
87-
);
88-
CREATE UNIQUE INDEX pk_mail_status_idx ON mail_status(mail_id);
89-
9084
CREATE TABLE header (
9185
mail_id INT REFERENCES mail(mail_id),
9286
lines TEXT
@@ -382,56 +376,6 @@ my %object_comments=(
382376
);
383377

384378
my %functions=(
385-
"insert_mail" => <<'EOFUNCTION'
386-
CREATE OR REPLACE FUNCTION insert_mail() RETURNS TRIGGER AS $$
387-
BEGIN
388-
IF NEW.status&(256+32+16)=0 THEN
389-
-- The message is not yet sent, archived, or trashed
390-
INSERT INTO mail_status(mail_id,status) VALUES(new.mail_id,new.status);
391-
END IF;
392-
RETURN new;
393-
END;
394-
$$ LANGUAGE 'plpgsql'
395-
EOFUNCTION
396-
,
397-
398-
"update_mail" => <<'EOFUNCTION'
399-
CREATE OR REPLACE FUNCTION update_mail() RETURNS TRIGGER AS $$
400-
DECLARE
401-
rc int4;
402-
BEGIN
403-
IF new.status!=old.status THEN
404-
IF NEW.status&(256+32+16)=0 THEN
405-
-- The message is not yet sent, archived, or trashed
406-
UPDATE mail_status
407-
SET status = new.status
408-
WHERE mail_id = new.mail_id;
409-
GET DIAGNOSTICS rc = ROW_COUNT;
410-
if rc=0 THEN
411-
INSERT INTO mail_status(mail_id,status) VALUES(new.mail_id,new.status);
412-
END IF;
413-
ELSE
414-
-- The mail has been "processed"
415-
DELETE FROM mail_status
416-
WHERE mail_id = new.mail_id;
417-
END IF;
418-
END IF;
419-
RETURN new;
420-
END;
421-
$$ LANGUAGE 'plpgsql'
422-
EOFUNCTION
423-
,
424-
425-
"delete_mail" => <<'EOFUNCTION'
426-
CREATE OR REPLACE FUNCTION delete_mail() RETURNS TRIGGER AS $$
427-
BEGIN
428-
DELETE FROM mail_status WHERE mail_id=OLD.mail_id;
429-
RETURN old;
430-
END;
431-
$$ LANGUAGE 'plpgsql'
432-
EOFUNCTION
433-
,
434-
435379
"delete_msg" => <<'EOFUNCTION'
436380
CREATE OR REPLACE FUNCTION delete_msg(integer) RETURNS integer AS $$
437381
DECLARE
@@ -531,6 +475,19 @@ $$ language sql
531475
EOFUNCTION
532476
,
533477

478+
"status_mask" => <<'EOFUNCTION'
479+
CREATE OR REPLACE FUNCTION status_mask(text) returns int as $$
480+
select case $1
481+
when 'archived' then 32
482+
when 'read' then 1
483+
when 'replied' then 4
484+
when 'sent' then 256
485+
else null
486+
end
487+
$$ language sql immutable;
488+
EOFUNCTION
489+
,
490+
534491
"trash_msg" => <<'EOFUNCTION'
535492
CREATE OR REPLACE FUNCTION trash_msg(in_mail_id integer, in_op integer) RETURNS integer AS $$
536493
DECLARE
@@ -588,21 +545,21 @@ DECLARE
588545
tbl_ro text[]:='{
589546
"addresses", "attachment_contents", "attachments",
590547
"body", "config", "header", "identities", "identities_permissions",
591-
"mail", "mail_addresses", "mail_status", "mail_tags",
548+
"mail", "mail_addresses", "mail_tags",
592549
"notes", "runtime_info", "tags", "users", "user_queries" }';
593550
594551
-- the tables that need to be UPDATE'able for a read-write user
595552
tbl_upd text[]:='{
596553
"addresses", "attachment_contents", "attachments",
597554
"body", "config", "header", "mail",
598-
"mail_addresses", "mail_status", "mail_tags",
555+
"mail_addresses", "mail_tags",
599556
"notes" }';
600557
601558
-- the tables that need to be DELETE'able for a deleter
602559
tbl_del text[]:='{
603560
"attachment_contents", "attachments",
604561
"body", "header", "mail",
605-
"mail_addresses", "mail_status", "mail_tags",
562+
"mail_addresses", "mail_tags",
606563
"notes", "raw_mail" }';
607564
BEGIN
608565
IF ability = 'read' THEN
@@ -896,18 +853,8 @@ EOFUNCTION
896853
);
897854

898855
my %triggers=(
899-
"update_mail" => q{CREATE TRIGGER update_mail AFTER UPDATE ON mail
900-
FOR EACH ROW EXECUTE PROCEDURE update_mail()},
901-
902-
"insert_mail" => q{CREATE TRIGGER insert_mail AFTER INSERT ON mail
903-
FOR EACH ROW EXECUTE PROCEDURE insert_mail()},
904-
905-
"delete_mail" => q{CREATE TRIGGER delete_mail AFTER DELETE ON mail
906-
FOR EACH ROW EXECUTE PROCEDURE delete_mail()},
907-
908856
"update_note" => q{CREATE TRIGGER update_note AFTER INSERT OR DELETE ON notes
909857
FOR EACH ROW EXECUTE PROCEDURE update_note_flag()}
910-
911858
);
912859

913860
sub extract_statements {
@@ -1105,7 +1052,15 @@ sub upgrade_schema_statements {
11051052
}
11061053
elsif ($from eq "1.6.0" && $to eq "1.7.0") {
11071054
push @stmt, "ALTER TABLE identities ADD CONSTRAINT identities_email_addr_key UNIQUE(email_addr)";
1055+
push @stmt, "CREATE INDEX current_mail_idx ON mail(status) WHERE status&32=0";
1056+
push @stmt, "DROP TRIGGER insert_mail ON mail";
1057+
push @stmt, "DROP TRIGGER update_mail ON mail";
1058+
push @stmt, "DROP TRIGGER delete_mail ON mail";
1059+
push @stmt, $functions{"object_permissions"}; # updated to drop references to mail_status
1060+
push @stmt, $functions{"status_mask"};
1061+
push @stmt, "DROP TABLE mail_status";
11081062
}
1063+
11091064
return @stmt;
11101065
}
11111066

0 commit comments

Comments
 (0)