Project

General

Profile

1 5283 aaronmk
/* To get the place trigger, just search and replace taxonconcept with place. */
2 1561 aaronmk
3 1558 aaronmk
----- Trigger function
4
5 5283 aaronmk
-- Function: taxonconcept_update_ancestors()
6 1558 aaronmk
7 5283 aaronmk
-- DROP FUNCTION taxonconcept_update_ancestors();
8 1558 aaronmk
9 5283 aaronmk
CREATE OR REPLACE FUNCTION taxonconcept_update_ancestors()
10 1558 aaronmk
  RETURNS trigger AS
11
$BODY$
12
BEGIN
13 1559 aaronmk
    -- Delete existing ancestors
14 5283 aaronmk
    DELETE FROM taxonconcept_ancestor
15
    WHERE taxonconcept_id = new.taxonconcept_id;
16 1559 aaronmk
17 1558 aaronmk
    IF new.parent_id IS NOT NULL THEN
18
        -- Copy parent's ancestors to this node's ancestors
19
        INSERT
20 5283 aaronmk
        INTO taxonconcept_ancestor
21
        (taxonconcept_id, ancestor_id)
22 1558 aaronmk
        SELECT
23 5283 aaronmk
            new.taxonconcept_id, ancestor_id
24
        FROM taxonconcept_ancestor
25
        WHERE taxonconcept_id = new.parent_id
26 1558 aaronmk
        ;
27
    END IF;
28 1559 aaronmk
29
    -- Add "ancestor" for this node
30
    /* This is useful for queries, because you don't have to separately test if
31
    the leaf node is the one you're looking for, in addition to that leaf node's
32
    ancestors. */
33
    INSERT
34 5283 aaronmk
    INTO taxonconcept_ancestor
35
    (taxonconcept_id, ancestor_id)
36
    VALUES (new.taxonconcept_id, new.taxonconcept_id)
37 1559 aaronmk
    ;
38
39
    -- Tell immediate children to update their ancestors lists, which will
40
    -- recursively tell all descendants
41 5283 aaronmk
    UPDATE taxonconcept
42
    SET taxonconcept_id = taxonconcept_id -- need at least one SET statement
43
    -- Add COALESCE() to enable using taxonconcept_unique index for lookup
44
    WHERE COALESCE(parent_id, 2147483647) = new.taxonconcept_id
45 1559 aaronmk
    ;
46
47
    /* Note: We don't need an ON DELETE trigger to update the descendants'
48 5283 aaronmk
    ancestors when a node is deleted, because the taxonconcept.parent_id foreign
49
    key is ON DELETE CASCADE, which just removes all the descendants anyway. */
50 1559 aaronmk
51 1558 aaronmk
    RETURN new;
52
END;
53
$BODY$
54
  LANGUAGE plpgsql VOLATILE
55
  COST 100;
56 5283 aaronmk
ALTER FUNCTION taxonconcept_update_ancestors()
57 1558 aaronmk
  OWNER TO bien;
58
59
----- Ancestors table
60
61 5283 aaronmk
-- Table: taxonconcept_ancestor
62 1558 aaronmk
63 5283 aaronmk
-- DROP TABLE taxonconcept_ancestor;
64 1558 aaronmk
65 5283 aaronmk
CREATE TABLE taxonconcept_ancestor
66 1558 aaronmk
(
67 5283 aaronmk
  taxonconcept_id integer NOT NULL,
68 1558 aaronmk
  ancestor_id integer NOT NULL,
69 5283 aaronmk
  CONSTRAINT taxonconcept_ancestor_pkey PRIMARY KEY (taxonconcept_id , ancestor_id ),
70
  CONSTRAINT taxonconcept_ancestor_ancestor_id_fkey FOREIGN KEY (ancestor_id)
71
      REFERENCES taxonconcept (taxonconcept_id) MATCH SIMPLE
72 1558 aaronmk
      ON UPDATE CASCADE ON DELETE CASCADE,
73 5283 aaronmk
  CONSTRAINT taxonconcept_ancestor_taxonconcept_id_fkey FOREIGN KEY (taxonconcept_id)
74
      REFERENCES taxonconcept (taxonconcept_id) MATCH SIMPLE
75 1558 aaronmk
      ON UPDATE CASCADE ON DELETE CASCADE
76
)
77
WITH (
78
  OIDS=FALSE
79
);
80 5283 aaronmk
ALTER TABLE taxonconcept_ancestor
81 1558 aaronmk
  OWNER TO bien;
82
83
----- Trigger
84
85 5283 aaronmk
-- Trigger: taxonconcept_update_ancestors on taxonconcept
86 1558 aaronmk
87 5283 aaronmk
-- DROP TRIGGER taxonconcept_update_ancestors ON taxonconcept;
88 1558 aaronmk
89 5283 aaronmk
CREATE TRIGGER taxonconcept_update_ancestors
90 1558 aaronmk
  AFTER INSERT OR UPDATE
91 5283 aaronmk
  ON taxonconcept
92 1558 aaronmk
  FOR EACH ROW
93 5283 aaronmk
  EXECUTE PROCEDURE taxonconcept_update_ancestors();