| rev | 
   line source | 
| 
jbe@67
 | 
     1 BEGIN;
 | 
| 
jbe@67
 | 
     2 
 | 
| 
jbe@67
 | 
     3 
 | 
| 
jbe@67
 | 
     4 CREATE OR REPLACE VIEW "liquid_feedback_version" AS
 | 
| 
jbe@67
 | 
     5   SELECT * FROM (VALUES ('1.2.5', 1, 2, 5))
 | 
| 
jbe@67
 | 
     6    AS "subquery"("string", "major", "minor", "revision");
 | 
| 
jbe@67
 | 
     7 
 | 
| 
jbe@67
 | 
     8 
 | 
| 
jbe@67
 | 
     9 CREATE FUNCTION "share_row_lock_issue_trigger"()
 | 
| 
jbe@67
 | 
    10   RETURNS TRIGGER
 | 
| 
jbe@67
 | 
    11   LANGUAGE 'plpgsql' VOLATILE AS $$
 | 
| 
jbe@67
 | 
    12     BEGIN
 | 
| 
jbe@67
 | 
    13       IF TG_OP = 'UPDATE' OR TG_OP = 'DELETE' THEN
 | 
| 
jbe@67
 | 
    14         PERFORM NULL FROM "issue" WHERE "id" = OLD."issue_id" FOR SHARE;
 | 
| 
jbe@67
 | 
    15       END IF;
 | 
| 
jbe@67
 | 
    16       IF TG_OP = 'INSERT' OR TG_OP = 'UPDATE' THEN
 | 
| 
jbe@67
 | 
    17         PERFORM NULL FROM "issue" WHERE "id" = NEW."issue_id" FOR SHARE;
 | 
| 
jbe@67
 | 
    18         RETURN NEW;
 | 
| 
jbe@67
 | 
    19       ELSE
 | 
| 
jbe@67
 | 
    20         RETURN OLD;
 | 
| 
jbe@67
 | 
    21       END IF;
 | 
| 
jbe@67
 | 
    22     END;
 | 
| 
jbe@67
 | 
    23   $$;
 | 
| 
jbe@67
 | 
    24 
 | 
| 
jbe@67
 | 
    25 COMMENT ON FUNCTION "share_row_lock_issue_trigger"() IS 'Implementation of triggers "share_row_lock_issue" on multiple tables';
 | 
| 
jbe@67
 | 
    26 
 | 
| 
jbe@67
 | 
    27 
 | 
| 
jbe@67
 | 
    28 CREATE FUNCTION "share_row_lock_issue_via_initiative_trigger"()
 | 
| 
jbe@67
 | 
    29   RETURNS TRIGGER
 | 
| 
jbe@67
 | 
    30   LANGUAGE 'plpgsql' VOLATILE AS $$
 | 
| 
jbe@67
 | 
    31     BEGIN
 | 
| 
jbe@67
 | 
    32       IF TG_OP = 'UPDATE' OR TG_OP = 'DELETE' THEN
 | 
| 
jbe@67
 | 
    33         PERFORM NULL FROM "issue"
 | 
| 
jbe@67
 | 
    34           JOIN "initiative" ON "issue"."id" = "initiative"."issue_id"
 | 
| 
jbe@67
 | 
    35           WHERE "initiative"."id" = OLD."initiative_id"
 | 
| 
jbe@67
 | 
    36           FOR SHARE OF "issue";
 | 
| 
jbe@67
 | 
    37       END IF;
 | 
| 
jbe@67
 | 
    38       IF TG_OP = 'INSERT' OR TG_OP = 'UPDATE' THEN
 | 
| 
jbe@67
 | 
    39         PERFORM NULL FROM "issue"
 | 
| 
jbe@67
 | 
    40           JOIN "initiative" ON "issue"."id" = "initiative"."issue_id"
 | 
| 
jbe@67
 | 
    41           WHERE "initiative"."id" = NEW."initiative_id"
 | 
| 
jbe@67
 | 
    42           FOR SHARE OF "issue";
 | 
| 
jbe@67
 | 
    43         RETURN NEW;
 | 
| 
jbe@67
 | 
    44       ELSE
 | 
| 
jbe@67
 | 
    45         RETURN OLD;
 | 
| 
jbe@67
 | 
    46       END IF;
 | 
| 
jbe@67
 | 
    47     END;
 | 
| 
jbe@67
 | 
    48   $$;
 | 
| 
jbe@67
 | 
    49 
 | 
| 
jbe@67
 | 
    50 COMMENT ON FUNCTION "share_row_lock_issue_trigger"() IS 'Implementation of trigger "share_row_lock_issue_via_initiative" on table "opinion"';
 | 
| 
jbe@67
 | 
    51 
 | 
| 
jbe@67
 | 
    52 
 | 
| 
jbe@67
 | 
    53 CREATE TRIGGER "share_row_lock_issue"
 | 
| 
jbe@67
 | 
    54   BEFORE INSERT OR UPDATE OR DELETE ON "initiative"
 | 
| 
jbe@67
 | 
    55   FOR EACH ROW EXECUTE PROCEDURE
 | 
| 
jbe@67
 | 
    56   "share_row_lock_issue_trigger"();
 | 
| 
jbe@67
 | 
    57 
 | 
| 
jbe@67
 | 
    58 CREATE TRIGGER "share_row_lock_issue"
 | 
| 
jbe@67
 | 
    59   BEFORE INSERT OR UPDATE OR DELETE ON "interest"
 | 
| 
jbe@67
 | 
    60   FOR EACH ROW EXECUTE PROCEDURE
 | 
| 
jbe@67
 | 
    61   "share_row_lock_issue_trigger"();
 | 
| 
jbe@67
 | 
    62 
 | 
| 
jbe@67
 | 
    63 CREATE TRIGGER "share_row_lock_issue"
 | 
| 
jbe@67
 | 
    64   BEFORE INSERT OR UPDATE OR DELETE ON "supporter"
 | 
| 
jbe@67
 | 
    65   FOR EACH ROW EXECUTE PROCEDURE
 | 
| 
jbe@67
 | 
    66   "share_row_lock_issue_trigger"();
 | 
| 
jbe@67
 | 
    67 
 | 
| 
jbe@67
 | 
    68 CREATE TRIGGER "share_row_lock_issue_via_initiative"
 | 
| 
jbe@67
 | 
    69   BEFORE INSERT OR UPDATE OR DELETE ON "opinion"
 | 
| 
jbe@67
 | 
    70   FOR EACH ROW EXECUTE PROCEDURE
 | 
| 
jbe@67
 | 
    71   "share_row_lock_issue_via_initiative_trigger"();
 | 
| 
jbe@67
 | 
    72 
 | 
| 
jbe@67
 | 
    73 CREATE TRIGGER "share_row_lock_issue"
 | 
| 
jbe@67
 | 
    74   BEFORE INSERT OR UPDATE OR DELETE ON "direct_voter"
 | 
| 
jbe@67
 | 
    75   FOR EACH ROW EXECUTE PROCEDURE
 | 
| 
jbe@67
 | 
    76   "share_row_lock_issue_trigger"();
 | 
| 
jbe@67
 | 
    77 
 | 
| 
jbe@67
 | 
    78 CREATE TRIGGER "share_row_lock_issue"
 | 
| 
jbe@67
 | 
    79   BEFORE INSERT OR UPDATE OR DELETE ON "delegating_voter"
 | 
| 
jbe@67
 | 
    80   FOR EACH ROW EXECUTE PROCEDURE
 | 
| 
jbe@67
 | 
    81   "share_row_lock_issue_trigger"();
 | 
| 
jbe@67
 | 
    82 
 | 
| 
jbe@67
 | 
    83 CREATE TRIGGER "share_row_lock_issue"
 | 
| 
jbe@67
 | 
    84   BEFORE INSERT OR UPDATE OR DELETE ON "vote"
 | 
| 
jbe@67
 | 
    85   FOR EACH ROW EXECUTE PROCEDURE
 | 
| 
jbe@67
 | 
    86   "share_row_lock_issue_trigger"();
 | 
| 
jbe@67
 | 
    87 
 | 
| 
jbe@67
 | 
    88 COMMENT ON TRIGGER "share_row_lock_issue"                ON "initiative"       IS 'See "lock_issue" function';
 | 
| 
jbe@67
 | 
    89 COMMENT ON TRIGGER "share_row_lock_issue"                ON "interest"         IS 'See "lock_issue" function';
 | 
| 
jbe@67
 | 
    90 COMMENT ON TRIGGER "share_row_lock_issue"                ON "supporter"        IS 'See "lock_issue" function';
 | 
| 
jbe@67
 | 
    91 COMMENT ON TRIGGER "share_row_lock_issue_via_initiative" ON "opinion"          IS 'See "lock_issue" function';
 | 
| 
jbe@67
 | 
    92 COMMENT ON TRIGGER "share_row_lock_issue"                ON "direct_voter"     IS 'See "lock_issue" function';
 | 
| 
jbe@67
 | 
    93 COMMENT ON TRIGGER "share_row_lock_issue"                ON "delegating_voter" IS 'See "lock_issue" function';
 | 
| 
jbe@67
 | 
    94 COMMENT ON TRIGGER "share_row_lock_issue"                ON "vote"             IS 'See "lock_issue" function';
 | 
| 
jbe@67
 | 
    95 
 | 
| 
jbe@67
 | 
    96 
 | 
| 
jbe@67
 | 
    97 CREATE FUNCTION "lock_issue"
 | 
| 
jbe@67
 | 
    98   ( "issue_id_p" "issue"."id"%TYPE )
 | 
| 
jbe@67
 | 
    99   RETURNS VOID
 | 
| 
jbe@67
 | 
   100   LANGUAGE 'plpgsql' VOLATILE AS $$
 | 
| 
jbe@67
 | 
   101     BEGIN
 | 
| 
jbe@67
 | 
   102       LOCK TABLE "member"     IN SHARE MODE;
 | 
| 
jbe@67
 | 
   103       LOCK TABLE "membership" IN SHARE MODE;
 | 
| 
jbe@67
 | 
   104       LOCK TABLE "policy"     IN SHARE MODE;
 | 
| 
jbe@67
 | 
   105       PERFORM NULL FROM "issue" WHERE "id" = "issue_id_p" FOR UPDATE;
 | 
| 
jbe@67
 | 
   106       -- NOTE: The row-level exclusive lock in combination with the
 | 
| 
jbe@67
 | 
   107       -- share_row_lock_issue(_via_initiative)_trigger functions (which
 | 
| 
jbe@67
 | 
   108       -- acquire a row-level share lock on the issue) ensure that no data
 | 
| 
jbe@67
 | 
   109       -- is changed, which could affect calculation of snapshots or
 | 
| 
jbe@67
 | 
   110       -- counting of votes. Table "delegation" must be table-level-locked,
 | 
| 
jbe@67
 | 
   111       -- as it also contains issue- and global-scope delegations.
 | 
| 
jbe@67
 | 
   112       LOCK TABLE "delegation" IN SHARE MODE;
 | 
| 
jbe@67
 | 
   113       LOCK TABLE "direct_population_snapshot"     IN EXCLUSIVE MODE;
 | 
| 
jbe@67
 | 
   114       LOCK TABLE "delegating_population_snapshot" IN EXCLUSIVE MODE;
 | 
| 
jbe@67
 | 
   115       LOCK TABLE "direct_interest_snapshot"       IN EXCLUSIVE MODE;
 | 
| 
jbe@67
 | 
   116       LOCK TABLE "delegating_interest_snapshot"   IN EXCLUSIVE MODE;
 | 
| 
jbe@67
 | 
   117       LOCK TABLE "direct_supporter_snapshot"      IN EXCLUSIVE MODE;
 | 
| 
jbe@67
 | 
   118       RETURN;
 | 
| 
jbe@67
 | 
   119     END;
 | 
| 
jbe@67
 | 
   120   $$;
 | 
| 
jbe@67
 | 
   121 
 | 
| 
jbe@67
 | 
   122 COMMENT ON FUNCTION "lock_issue"
 | 
| 
jbe@67
 | 
   123   ( "issue"."id"%TYPE )
 | 
| 
jbe@67
 | 
   124   IS 'Locks the issue and all other data which is used for calculating snapshots or counting votes.';
 | 
| 
jbe@67
 | 
   125 
 | 
| 
jbe@67
 | 
   126 
 | 
| 
jbe@67
 | 
   127 CREATE OR REPLACE FUNCTION "calculate_member_counts"()
 | 
| 
jbe@67
 | 
   128   RETURNS VOID
 | 
| 
jbe@67
 | 
   129   LANGUAGE 'plpgsql' VOLATILE AS $$
 | 
| 
jbe@67
 | 
   130     BEGIN
 | 
| 
jbe@67
 | 
   131       LOCK TABLE "member"       IN SHARE MODE;
 | 
| 
jbe@67
 | 
   132       LOCK TABLE "member_count" IN EXCLUSIVE MODE;
 | 
| 
jbe@67
 | 
   133       LOCK TABLE "area"         IN EXCLUSIVE MODE;
 | 
| 
jbe@67
 | 
   134       LOCK TABLE "membership"   IN SHARE MODE;
 | 
| 
jbe@67
 | 
   135       DELETE FROM "member_count";
 | 
| 
jbe@67
 | 
   136       INSERT INTO "member_count" ("total_count")
 | 
| 
jbe@67
 | 
   137         SELECT "total_count" FROM "member_count_view";
 | 
| 
jbe@67
 | 
   138       UPDATE "area" SET
 | 
| 
jbe@67
 | 
   139         "direct_member_count" = "view"."direct_member_count",
 | 
| 
jbe@67
 | 
   140         "member_weight"       = "view"."member_weight",
 | 
| 
jbe@67
 | 
   141         "autoreject_weight"   = "view"."autoreject_weight"
 | 
| 
jbe@67
 | 
   142         FROM "area_member_count" AS "view"
 | 
| 
jbe@67
 | 
   143         WHERE "view"."area_id" = "area"."id";
 | 
| 
jbe@67
 | 
   144       RETURN;
 | 
| 
jbe@67
 | 
   145     END;
 | 
| 
jbe@67
 | 
   146   $$;
 | 
| 
jbe@67
 | 
   147 
 | 
| 
jbe@67
 | 
   148 CREATE OR REPLACE FUNCTION "create_snapshot"
 | 
| 
jbe@67
 | 
   149   ( "issue_id_p" "issue"."id"%TYPE )
 | 
| 
jbe@67
 | 
   150   RETURNS VOID
 | 
| 
jbe@67
 | 
   151   LANGUAGE 'plpgsql' VOLATILE AS $$
 | 
| 
jbe@67
 | 
   152     DECLARE
 | 
| 
jbe@67
 | 
   153       "initiative_id_v"    "initiative"."id"%TYPE;
 | 
| 
jbe@67
 | 
   154       "suggestion_id_v"    "suggestion"."id"%TYPE;
 | 
| 
jbe@67
 | 
   155     BEGIN
 | 
| 
jbe@67
 | 
   156       PERFORM "lock_issue"("issue_id_p");
 | 
| 
jbe@67
 | 
   157       PERFORM "create_population_snapshot"("issue_id_p");
 | 
| 
jbe@67
 | 
   158       PERFORM "create_interest_snapshot"("issue_id_p");
 | 
| 
jbe@67
 | 
   159       UPDATE "issue" SET
 | 
| 
jbe@67
 | 
   160         "snapshot" = now(),
 | 
| 
jbe@67
 | 
   161         "latest_snapshot_event" = 'periodic',
 | 
| 
jbe@67
 | 
   162         "population" = (
 | 
| 
jbe@67
 | 
   163           SELECT coalesce(sum("weight"), 0)
 | 
| 
jbe@67
 | 
   164           FROM "direct_population_snapshot"
 | 
| 
jbe@67
 | 
   165           WHERE "issue_id" = "issue_id_p"
 | 
| 
jbe@67
 | 
   166           AND "event" = 'periodic'
 | 
| 
jbe@67
 | 
   167         ),
 | 
| 
jbe@67
 | 
   168         "vote_now" = (
 | 
| 
jbe@67
 | 
   169           SELECT coalesce(sum("weight"), 0)
 | 
| 
jbe@67
 | 
   170           FROM "direct_interest_snapshot"
 | 
| 
jbe@67
 | 
   171           WHERE "issue_id" = "issue_id_p"
 | 
| 
jbe@67
 | 
   172           AND "event" = 'periodic'
 | 
| 
jbe@67
 | 
   173           AND "voting_requested" = TRUE
 | 
| 
jbe@67
 | 
   174         ),
 | 
| 
jbe@67
 | 
   175         "vote_later" = (
 | 
| 
jbe@67
 | 
   176           SELECT coalesce(sum("weight"), 0)
 | 
| 
jbe@67
 | 
   177           FROM "direct_interest_snapshot"
 | 
| 
jbe@67
 | 
   178           WHERE "issue_id" = "issue_id_p"
 | 
| 
jbe@67
 | 
   179           AND "event" = 'periodic'
 | 
| 
jbe@67
 | 
   180           AND "voting_requested" = FALSE
 | 
| 
jbe@67
 | 
   181         )
 | 
| 
jbe@67
 | 
   182         WHERE "id" = "issue_id_p";
 | 
| 
jbe@67
 | 
   183       FOR "initiative_id_v" IN
 | 
| 
jbe@67
 | 
   184         SELECT "id" FROM "initiative" WHERE "issue_id" = "issue_id_p"
 | 
| 
jbe@67
 | 
   185       LOOP
 | 
| 
jbe@67
 | 
   186         UPDATE "initiative" SET
 | 
| 
jbe@67
 | 
   187           "supporter_count" = (
 | 
| 
jbe@67
 | 
   188             SELECT coalesce(sum("di"."weight"), 0)
 | 
| 
jbe@67
 | 
   189             FROM "direct_interest_snapshot" AS "di"
 | 
| 
jbe@67
 | 
   190             JOIN "direct_supporter_snapshot" AS "ds"
 | 
| 
jbe@67
 | 
   191             ON "di"."member_id" = "ds"."member_id"
 | 
| 
jbe@67
 | 
   192             WHERE "di"."issue_id" = "issue_id_p"
 | 
| 
jbe@67
 | 
   193             AND "di"."event" = 'periodic'
 | 
| 
jbe@67
 | 
   194             AND "ds"."initiative_id" = "initiative_id_v"
 | 
| 
jbe@67
 | 
   195             AND "ds"."event" = 'periodic'
 | 
| 
jbe@67
 | 
   196           ),
 | 
| 
jbe@67
 | 
   197           "informed_supporter_count" = (
 | 
| 
jbe@67
 | 
   198             SELECT coalesce(sum("di"."weight"), 0)
 | 
| 
jbe@67
 | 
   199             FROM "direct_interest_snapshot" AS "di"
 | 
| 
jbe@67
 | 
   200             JOIN "direct_supporter_snapshot" AS "ds"
 | 
| 
jbe@67
 | 
   201             ON "di"."member_id" = "ds"."member_id"
 | 
| 
jbe@67
 | 
   202             WHERE "di"."issue_id" = "issue_id_p"
 | 
| 
jbe@67
 | 
   203             AND "di"."event" = 'periodic'
 | 
| 
jbe@67
 | 
   204             AND "ds"."initiative_id" = "initiative_id_v"
 | 
| 
jbe@67
 | 
   205             AND "ds"."event" = 'periodic'
 | 
| 
jbe@67
 | 
   206             AND "ds"."informed"
 | 
| 
jbe@67
 | 
   207           ),
 | 
| 
jbe@67
 | 
   208           "satisfied_supporter_count" = (
 | 
| 
jbe@67
 | 
   209             SELECT coalesce(sum("di"."weight"), 0)
 | 
| 
jbe@67
 | 
   210             FROM "direct_interest_snapshot" AS "di"
 | 
| 
jbe@67
 | 
   211             JOIN "direct_supporter_snapshot" AS "ds"
 | 
| 
jbe@67
 | 
   212             ON "di"."member_id" = "ds"."member_id"
 | 
| 
jbe@67
 | 
   213             WHERE "di"."issue_id" = "issue_id_p"
 | 
| 
jbe@67
 | 
   214             AND "di"."event" = 'periodic'
 | 
| 
jbe@67
 | 
   215             AND "ds"."initiative_id" = "initiative_id_v"
 | 
| 
jbe@67
 | 
   216             AND "ds"."event" = 'periodic'
 | 
| 
jbe@67
 | 
   217             AND "ds"."satisfied"
 | 
| 
jbe@67
 | 
   218           ),
 | 
| 
jbe@67
 | 
   219           "satisfied_informed_supporter_count" = (
 | 
| 
jbe@67
 | 
   220             SELECT coalesce(sum("di"."weight"), 0)
 | 
| 
jbe@67
 | 
   221             FROM "direct_interest_snapshot" AS "di"
 | 
| 
jbe@67
 | 
   222             JOIN "direct_supporter_snapshot" AS "ds"
 | 
| 
jbe@67
 | 
   223             ON "di"."member_id" = "ds"."member_id"
 | 
| 
jbe@67
 | 
   224             WHERE "di"."issue_id" = "issue_id_p"
 | 
| 
jbe@67
 | 
   225             AND "di"."event" = 'periodic'
 | 
| 
jbe@67
 | 
   226             AND "ds"."initiative_id" = "initiative_id_v"
 | 
| 
jbe@67
 | 
   227             AND "ds"."event" = 'periodic'
 | 
| 
jbe@67
 | 
   228             AND "ds"."informed"
 | 
| 
jbe@67
 | 
   229             AND "ds"."satisfied"
 | 
| 
jbe@67
 | 
   230           )
 | 
| 
jbe@67
 | 
   231           WHERE "id" = "initiative_id_v";
 | 
| 
jbe@67
 | 
   232         FOR "suggestion_id_v" IN
 | 
| 
jbe@67
 | 
   233           SELECT "id" FROM "suggestion"
 | 
| 
jbe@67
 | 
   234           WHERE "initiative_id" = "initiative_id_v"
 | 
| 
jbe@67
 | 
   235         LOOP
 | 
| 
jbe@67
 | 
   236           UPDATE "suggestion" SET
 | 
| 
jbe@67
 | 
   237             "minus2_unfulfilled_count" = (
 | 
| 
jbe@67
 | 
   238               SELECT coalesce(sum("snapshot"."weight"), 0)
 | 
| 
jbe@67
 | 
   239               FROM "issue" CROSS JOIN "opinion"
 | 
| 
jbe@67
 | 
   240               JOIN "direct_interest_snapshot" AS "snapshot"
 | 
| 
jbe@67
 | 
   241               ON "snapshot"."issue_id" = "issue"."id"
 | 
| 
jbe@67
 | 
   242               AND "snapshot"."event" = "issue"."latest_snapshot_event"
 | 
| 
jbe@67
 | 
   243               AND "snapshot"."member_id" = "opinion"."member_id"
 | 
| 
jbe@67
 | 
   244               WHERE "issue"."id" = "issue_id_p"
 | 
| 
jbe@67
 | 
   245               AND "opinion"."suggestion_id" = "suggestion_id_v"
 | 
| 
jbe@67
 | 
   246               AND "opinion"."degree" = -2
 | 
| 
jbe@67
 | 
   247               AND "opinion"."fulfilled" = FALSE
 | 
| 
jbe@67
 | 
   248             ),
 | 
| 
jbe@67
 | 
   249             "minus2_fulfilled_count" = (
 | 
| 
jbe@67
 | 
   250               SELECT coalesce(sum("snapshot"."weight"), 0)
 | 
| 
jbe@67
 | 
   251               FROM "issue" CROSS JOIN "opinion"
 | 
| 
jbe@67
 | 
   252               JOIN "direct_interest_snapshot" AS "snapshot"
 | 
| 
jbe@67
 | 
   253               ON "snapshot"."issue_id" = "issue"."id"
 | 
| 
jbe@67
 | 
   254               AND "snapshot"."event" = "issue"."latest_snapshot_event"
 | 
| 
jbe@67
 | 
   255               AND "snapshot"."member_id" = "opinion"."member_id"
 | 
| 
jbe@67
 | 
   256               WHERE "issue"."id" = "issue_id_p"
 | 
| 
jbe@67
 | 
   257               AND "opinion"."suggestion_id" = "suggestion_id_v"
 | 
| 
jbe@67
 | 
   258               AND "opinion"."degree" = -2
 | 
| 
jbe@67
 | 
   259               AND "opinion"."fulfilled" = TRUE
 | 
| 
jbe@67
 | 
   260             ),
 | 
| 
jbe@67
 | 
   261             "minus1_unfulfilled_count" = (
 | 
| 
jbe@67
 | 
   262               SELECT coalesce(sum("snapshot"."weight"), 0)
 | 
| 
jbe@67
 | 
   263               FROM "issue" CROSS JOIN "opinion"
 | 
| 
jbe@67
 | 
   264               JOIN "direct_interest_snapshot" AS "snapshot"
 | 
| 
jbe@67
 | 
   265               ON "snapshot"."issue_id" = "issue"."id"
 | 
| 
jbe@67
 | 
   266               AND "snapshot"."event" = "issue"."latest_snapshot_event"
 | 
| 
jbe@67
 | 
   267               AND "snapshot"."member_id" = "opinion"."member_id"
 | 
| 
jbe@67
 | 
   268               WHERE "issue"."id" = "issue_id_p"
 | 
| 
jbe@67
 | 
   269               AND "opinion"."suggestion_id" = "suggestion_id_v"
 | 
| 
jbe@67
 | 
   270               AND "opinion"."degree" = -1
 | 
| 
jbe@67
 | 
   271               AND "opinion"."fulfilled" = FALSE
 | 
| 
jbe@67
 | 
   272             ),
 | 
| 
jbe@67
 | 
   273             "minus1_fulfilled_count" = (
 | 
| 
jbe@67
 | 
   274               SELECT coalesce(sum("snapshot"."weight"), 0)
 | 
| 
jbe@67
 | 
   275               FROM "issue" CROSS JOIN "opinion"
 | 
| 
jbe@67
 | 
   276               JOIN "direct_interest_snapshot" AS "snapshot"
 | 
| 
jbe@67
 | 
   277               ON "snapshot"."issue_id" = "issue"."id"
 | 
| 
jbe@67
 | 
   278               AND "snapshot"."event" = "issue"."latest_snapshot_event"
 | 
| 
jbe@67
 | 
   279               AND "snapshot"."member_id" = "opinion"."member_id"
 | 
| 
jbe@67
 | 
   280               WHERE "issue"."id" = "issue_id_p"
 | 
| 
jbe@67
 | 
   281               AND "opinion"."suggestion_id" = "suggestion_id_v"
 | 
| 
jbe@67
 | 
   282               AND "opinion"."degree" = -1
 | 
| 
jbe@67
 | 
   283               AND "opinion"."fulfilled" = TRUE
 | 
| 
jbe@67
 | 
   284             ),
 | 
| 
jbe@67
 | 
   285             "plus1_unfulfilled_count" = (
 | 
| 
jbe@67
 | 
   286               SELECT coalesce(sum("snapshot"."weight"), 0)
 | 
| 
jbe@67
 | 
   287               FROM "issue" CROSS JOIN "opinion"
 | 
| 
jbe@67
 | 
   288               JOIN "direct_interest_snapshot" AS "snapshot"
 | 
| 
jbe@67
 | 
   289               ON "snapshot"."issue_id" = "issue"."id"
 | 
| 
jbe@67
 | 
   290               AND "snapshot"."event" = "issue"."latest_snapshot_event"
 | 
| 
jbe@67
 | 
   291               AND "snapshot"."member_id" = "opinion"."member_id"
 | 
| 
jbe@67
 | 
   292               WHERE "issue"."id" = "issue_id_p"
 | 
| 
jbe@67
 | 
   293               AND "opinion"."suggestion_id" = "suggestion_id_v"
 | 
| 
jbe@67
 | 
   294               AND "opinion"."degree" = 1
 | 
| 
jbe@67
 | 
   295               AND "opinion"."fulfilled" = FALSE
 | 
| 
jbe@67
 | 
   296             ),
 | 
| 
jbe@67
 | 
   297             "plus1_fulfilled_count" = (
 | 
| 
jbe@67
 | 
   298               SELECT coalesce(sum("snapshot"."weight"), 0)
 | 
| 
jbe@67
 | 
   299               FROM "issue" CROSS JOIN "opinion"
 | 
| 
jbe@67
 | 
   300               JOIN "direct_interest_snapshot" AS "snapshot"
 | 
| 
jbe@67
 | 
   301               ON "snapshot"."issue_id" = "issue"."id"
 | 
| 
jbe@67
 | 
   302               AND "snapshot"."event" = "issue"."latest_snapshot_event"
 | 
| 
jbe@67
 | 
   303               AND "snapshot"."member_id" = "opinion"."member_id"
 | 
| 
jbe@67
 | 
   304               WHERE "issue"."id" = "issue_id_p"
 | 
| 
jbe@67
 | 
   305               AND "opinion"."suggestion_id" = "suggestion_id_v"
 | 
| 
jbe@67
 | 
   306               AND "opinion"."degree" = 1
 | 
| 
jbe@67
 | 
   307               AND "opinion"."fulfilled" = TRUE
 | 
| 
jbe@67
 | 
   308             ),
 | 
| 
jbe@67
 | 
   309             "plus2_unfulfilled_count" = (
 | 
| 
jbe@67
 | 
   310               SELECT coalesce(sum("snapshot"."weight"), 0)
 | 
| 
jbe@67
 | 
   311               FROM "issue" CROSS JOIN "opinion"
 | 
| 
jbe@67
 | 
   312               JOIN "direct_interest_snapshot" AS "snapshot"
 | 
| 
jbe@67
 | 
   313               ON "snapshot"."issue_id" = "issue"."id"
 | 
| 
jbe@67
 | 
   314               AND "snapshot"."event" = "issue"."latest_snapshot_event"
 | 
| 
jbe@67
 | 
   315               AND "snapshot"."member_id" = "opinion"."member_id"
 | 
| 
jbe@67
 | 
   316               WHERE "issue"."id" = "issue_id_p"
 | 
| 
jbe@67
 | 
   317               AND "opinion"."suggestion_id" = "suggestion_id_v"
 | 
| 
jbe@67
 | 
   318               AND "opinion"."degree" = 2
 | 
| 
jbe@67
 | 
   319               AND "opinion"."fulfilled" = FALSE
 | 
| 
jbe@67
 | 
   320             ),
 | 
| 
jbe@67
 | 
   321             "plus2_fulfilled_count" = (
 | 
| 
jbe@67
 | 
   322               SELECT coalesce(sum("snapshot"."weight"), 0)
 | 
| 
jbe@67
 | 
   323               FROM "issue" CROSS JOIN "opinion"
 | 
| 
jbe@67
 | 
   324               JOIN "direct_interest_snapshot" AS "snapshot"
 | 
| 
jbe@67
 | 
   325               ON "snapshot"."issue_id" = "issue"."id"
 | 
| 
jbe@67
 | 
   326               AND "snapshot"."event" = "issue"."latest_snapshot_event"
 | 
| 
jbe@67
 | 
   327               AND "snapshot"."member_id" = "opinion"."member_id"
 | 
| 
jbe@67
 | 
   328               WHERE "issue"."id" = "issue_id_p"
 | 
| 
jbe@67
 | 
   329               AND "opinion"."suggestion_id" = "suggestion_id_v"
 | 
| 
jbe@67
 | 
   330               AND "opinion"."degree" = 2
 | 
| 
jbe@67
 | 
   331               AND "opinion"."fulfilled" = TRUE
 | 
| 
jbe@67
 | 
   332             )
 | 
| 
jbe@67
 | 
   333             WHERE "suggestion"."id" = "suggestion_id_v";
 | 
| 
jbe@67
 | 
   334         END LOOP;
 | 
| 
jbe@67
 | 
   335       END LOOP;
 | 
| 
jbe@67
 | 
   336       RETURN;
 | 
| 
jbe@67
 | 
   337     END;
 | 
| 
jbe@67
 | 
   338   $$;
 | 
| 
jbe@67
 | 
   339 
 | 
| 
jbe@67
 | 
   340 CREATE OR REPLACE FUNCTION "close_voting"("issue_id_p" "issue"."id"%TYPE)
 | 
| 
jbe@67
 | 
   341   RETURNS VOID
 | 
| 
jbe@67
 | 
   342   LANGUAGE 'plpgsql' VOLATILE AS $$
 | 
| 
jbe@67
 | 
   343     DECLARE
 | 
| 
jbe@67
 | 
   344       "issue_row"   "issue"%ROWTYPE;
 | 
| 
jbe@67
 | 
   345       "member_id_v" "member"."id"%TYPE;
 | 
| 
jbe@67
 | 
   346     BEGIN
 | 
| 
jbe@67
 | 
   347       PERFORM "lock_issue"("issue_id_p");
 | 
| 
jbe@67
 | 
   348       SELECT * INTO "issue_row" FROM "issue" WHERE "id" = "issue_id_p";
 | 
| 
jbe@67
 | 
   349       DELETE FROM "delegating_voter"
 | 
| 
jbe@67
 | 
   350         WHERE "issue_id" = "issue_id_p";
 | 
| 
jbe@67
 | 
   351       DELETE FROM "direct_voter"
 | 
| 
jbe@67
 | 
   352         WHERE "issue_id" = "issue_id_p"
 | 
| 
jbe@67
 | 
   353         AND "autoreject" = TRUE;
 | 
| 
jbe@67
 | 
   354       DELETE FROM "direct_voter" USING "member"
 | 
| 
jbe@67
 | 
   355         WHERE "direct_voter"."member_id" = "member"."id"
 | 
| 
jbe@67
 | 
   356         AND "direct_voter"."issue_id" = "issue_id_p"
 | 
| 
jbe@67
 | 
   357         AND "member"."active" = FALSE;
 | 
| 
jbe@67
 | 
   358       UPDATE "direct_voter" SET "weight" = 1
 | 
| 
jbe@67
 | 
   359         WHERE "issue_id" = "issue_id_p";
 | 
| 
jbe@67
 | 
   360       PERFORM "add_vote_delegations"("issue_id_p");
 | 
| 
jbe@67
 | 
   361       FOR "member_id_v" IN
 | 
| 
jbe@67
 | 
   362         SELECT "interest"."member_id"
 | 
| 
jbe@67
 | 
   363           FROM "interest"
 | 
| 
jbe@67
 | 
   364           LEFT JOIN "direct_voter"
 | 
| 
jbe@67
 | 
   365             ON "interest"."member_id" = "direct_voter"."member_id"
 | 
| 
jbe@67
 | 
   366             AND "interest"."issue_id" = "direct_voter"."issue_id"
 | 
| 
jbe@67
 | 
   367           LEFT JOIN "delegating_voter"
 | 
| 
jbe@67
 | 
   368             ON "interest"."member_id" = "delegating_voter"."member_id"
 | 
| 
jbe@67
 | 
   369             AND "interest"."issue_id" = "delegating_voter"."issue_id"
 | 
| 
jbe@67
 | 
   370           WHERE "interest"."issue_id" = "issue_id_p"
 | 
| 
jbe@67
 | 
   371           AND "interest"."autoreject" = TRUE
 | 
| 
jbe@67
 | 
   372           AND "direct_voter"."member_id" ISNULL
 | 
| 
jbe@67
 | 
   373           AND "delegating_voter"."member_id" ISNULL
 | 
| 
jbe@67
 | 
   374         UNION SELECT "membership"."member_id"
 | 
| 
jbe@67
 | 
   375           FROM "membership"
 | 
| 
jbe@67
 | 
   376           LEFT JOIN "interest"
 | 
| 
jbe@67
 | 
   377             ON "membership"."member_id" = "interest"."member_id"
 | 
| 
jbe@67
 | 
   378             AND "interest"."issue_id" = "issue_id_p"
 | 
| 
jbe@67
 | 
   379           LEFT JOIN "direct_voter"
 | 
| 
jbe@67
 | 
   380             ON "membership"."member_id" = "direct_voter"."member_id"
 | 
| 
jbe@67
 | 
   381             AND "direct_voter"."issue_id" = "issue_id_p"
 | 
| 
jbe@67
 | 
   382           LEFT JOIN "delegating_voter"
 | 
| 
jbe@67
 | 
   383             ON "membership"."member_id" = "delegating_voter"."member_id"
 | 
| 
jbe@67
 | 
   384             AND "delegating_voter"."issue_id" = "issue_id_p"
 | 
| 
jbe@67
 | 
   385           WHERE "membership"."area_id" = "issue_row"."area_id"
 | 
| 
jbe@67
 | 
   386           AND "membership"."autoreject" = TRUE
 | 
| 
jbe@67
 | 
   387           AND "interest"."autoreject" ISNULL
 | 
| 
jbe@67
 | 
   388           AND "direct_voter"."member_id" ISNULL
 | 
| 
jbe@67
 | 
   389           AND "delegating_voter"."member_id" ISNULL
 | 
| 
jbe@67
 | 
   390       LOOP
 | 
| 
jbe@67
 | 
   391         INSERT INTO "direct_voter"
 | 
| 
jbe@67
 | 
   392           ("member_id", "issue_id", "weight", "autoreject") VALUES
 | 
| 
jbe@67
 | 
   393           ("member_id_v", "issue_id_p", 1, TRUE);
 | 
| 
jbe@67
 | 
   394         INSERT INTO "vote" (
 | 
| 
jbe@67
 | 
   395           "member_id",
 | 
| 
jbe@67
 | 
   396           "issue_id",
 | 
| 
jbe@67
 | 
   397           "initiative_id",
 | 
| 
jbe@67
 | 
   398           "grade"
 | 
| 
jbe@67
 | 
   399           ) SELECT
 | 
| 
jbe@67
 | 
   400             "member_id_v" AS "member_id",
 | 
| 
jbe@67
 | 
   401             "issue_id_p"  AS "issue_id",
 | 
| 
jbe@67
 | 
   402             "id"          AS "initiative_id",
 | 
| 
jbe@67
 | 
   403             -1            AS "grade"
 | 
| 
jbe@67
 | 
   404           FROM "initiative" WHERE "issue_id" = "issue_id_p";
 | 
| 
jbe@67
 | 
   405       END LOOP;
 | 
| 
jbe@67
 | 
   406       PERFORM "add_vote_delegations"("issue_id_p");
 | 
| 
jbe@67
 | 
   407       UPDATE "issue" SET
 | 
| 
jbe@67
 | 
   408         "closed" = now(),
 | 
| 
jbe@67
 | 
   409         "voter_count" = (
 | 
| 
jbe@67
 | 
   410           SELECT coalesce(sum("weight"), 0)
 | 
| 
jbe@67
 | 
   411           FROM "direct_voter" WHERE "issue_id" = "issue_id_p"
 | 
| 
jbe@67
 | 
   412         )
 | 
| 
jbe@67
 | 
   413         WHERE "id" = "issue_id_p";
 | 
| 
jbe@67
 | 
   414       UPDATE "initiative" SET
 | 
| 
jbe@67
 | 
   415         "positive_votes" = "vote_counts"."positive_votes",
 | 
| 
jbe@67
 | 
   416         "negative_votes" = "vote_counts"."negative_votes",
 | 
| 
jbe@67
 | 
   417         "agreed" = CASE WHEN "majority_strict" THEN
 | 
| 
jbe@67
 | 
   418           "vote_counts"."positive_votes" * "majority_den" >
 | 
| 
jbe@67
 | 
   419           "majority_num" *
 | 
| 
jbe@67
 | 
   420           ("vote_counts"."positive_votes"+"vote_counts"."negative_votes")
 | 
| 
jbe@67
 | 
   421         ELSE
 | 
| 
jbe@67
 | 
   422           "vote_counts"."positive_votes" * "majority_den" >=
 | 
| 
jbe@67
 | 
   423           "majority_num" *
 | 
| 
jbe@67
 | 
   424           ("vote_counts"."positive_votes"+"vote_counts"."negative_votes")
 | 
| 
jbe@67
 | 
   425         END
 | 
| 
jbe@67
 | 
   426         FROM
 | 
| 
jbe@67
 | 
   427           ( SELECT
 | 
| 
jbe@67
 | 
   428               "initiative"."id" AS "initiative_id",
 | 
| 
jbe@67
 | 
   429               coalesce(
 | 
| 
jbe@67
 | 
   430                 sum(
 | 
| 
jbe@67
 | 
   431                   CASE WHEN "grade" > 0 THEN "direct_voter"."weight" ELSE 0 END
 | 
| 
jbe@67
 | 
   432                 ),
 | 
| 
jbe@67
 | 
   433                 0
 | 
| 
jbe@67
 | 
   434               ) AS "positive_votes",
 | 
| 
jbe@67
 | 
   435               coalesce(
 | 
| 
jbe@67
 | 
   436                 sum(
 | 
| 
jbe@67
 | 
   437                   CASE WHEN "grade" < 0 THEN "direct_voter"."weight" ELSE 0 END
 | 
| 
jbe@67
 | 
   438                 ),
 | 
| 
jbe@67
 | 
   439                 0
 | 
| 
jbe@67
 | 
   440               ) AS "negative_votes"
 | 
| 
jbe@67
 | 
   441             FROM "initiative"
 | 
| 
jbe@67
 | 
   442             JOIN "issue" ON "initiative"."issue_id" = "issue"."id"
 | 
| 
jbe@67
 | 
   443             JOIN "policy" ON "issue"."policy_id" = "policy"."id"
 | 
| 
jbe@67
 | 
   444             LEFT JOIN "direct_voter"
 | 
| 
jbe@67
 | 
   445               ON "direct_voter"."issue_id" = "initiative"."issue_id"
 | 
| 
jbe@67
 | 
   446             LEFT JOIN "vote"
 | 
| 
jbe@67
 | 
   447               ON "vote"."initiative_id" = "initiative"."id"
 | 
| 
jbe@67
 | 
   448               AND "vote"."member_id" = "direct_voter"."member_id"
 | 
| 
jbe@67
 | 
   449             WHERE "initiative"."issue_id" = "issue_id_p"
 | 
| 
jbe@67
 | 
   450             AND "initiative"."admitted"  -- NOTE: NULL case is handled too
 | 
| 
jbe@67
 | 
   451             GROUP BY "initiative"."id"
 | 
| 
jbe@67
 | 
   452           ) AS "vote_counts",
 | 
| 
jbe@67
 | 
   453           "issue",
 | 
| 
jbe@67
 | 
   454           "policy"
 | 
| 
jbe@67
 | 
   455         WHERE "vote_counts"."initiative_id" = "initiative"."id"
 | 
| 
jbe@67
 | 
   456         AND "issue"."id" = "initiative"."issue_id"
 | 
| 
jbe@67
 | 
   457         AND "policy"."id" = "issue"."policy_id";
 | 
| 
jbe@67
 | 
   458       -- NOTE: "closed" column of issue must be set at this point
 | 
| 
jbe@67
 | 
   459       DELETE FROM "battle" WHERE "issue_id" = "issue_id_p";
 | 
| 
jbe@67
 | 
   460       INSERT INTO "battle" (
 | 
| 
jbe@67
 | 
   461         "issue_id",
 | 
| 
jbe@67
 | 
   462         "winning_initiative_id", "losing_initiative_id",
 | 
| 
jbe@67
 | 
   463         "count"
 | 
| 
jbe@67
 | 
   464       ) SELECT
 | 
| 
jbe@67
 | 
   465         "issue_id",
 | 
| 
jbe@67
 | 
   466         "winning_initiative_id", "losing_initiative_id",
 | 
| 
jbe@67
 | 
   467         "count"
 | 
| 
jbe@67
 | 
   468         FROM "battle_view" WHERE "issue_id" = "issue_id_p";
 | 
| 
jbe@67
 | 
   469     END;
 | 
| 
jbe@67
 | 
   470   $$;
 | 
| 
jbe@67
 | 
   471 
 | 
| 
jbe@67
 | 
   472 CREATE OR REPLACE FUNCTION "check_issue"
 | 
| 
jbe@67
 | 
   473   ( "issue_id_p" "issue"."id"%TYPE )
 | 
| 
jbe@67
 | 
   474   RETURNS VOID
 | 
| 
jbe@67
 | 
   475   LANGUAGE 'plpgsql' VOLATILE AS $$
 | 
| 
jbe@67
 | 
   476     DECLARE
 | 
| 
jbe@67
 | 
   477       "issue_row"         "issue"%ROWTYPE;
 | 
| 
jbe@67
 | 
   478       "policy_row"        "policy"%ROWTYPE;
 | 
| 
jbe@67
 | 
   479       "voting_requested_v" BOOLEAN;
 | 
| 
jbe@67
 | 
   480     BEGIN
 | 
| 
jbe@67
 | 
   481       PERFORM "lock_issue"("issue_id_p");
 | 
| 
jbe@67
 | 
   482       SELECT * INTO "issue_row" FROM "issue" WHERE "id" = "issue_id_p";
 | 
| 
jbe@67
 | 
   483       -- only process open issues:
 | 
| 
jbe@67
 | 
   484       IF "issue_row"."closed" ISNULL THEN
 | 
| 
jbe@67
 | 
   485         SELECT * INTO "policy_row" FROM "policy"
 | 
| 
jbe@67
 | 
   486           WHERE "id" = "issue_row"."policy_id";
 | 
| 
jbe@67
 | 
   487         -- create a snapshot, unless issue is already fully frozen:
 | 
| 
jbe@67
 | 
   488         IF "issue_row"."fully_frozen" ISNULL THEN
 | 
| 
jbe@67
 | 
   489           PERFORM "create_snapshot"("issue_id_p");
 | 
| 
jbe@67
 | 
   490           SELECT * INTO "issue_row" FROM "issue" WHERE "id" = "issue_id_p";
 | 
| 
jbe@67
 | 
   491         END IF;
 | 
| 
jbe@67
 | 
   492         -- eventually close or accept issues, which have not been accepted:
 | 
| 
jbe@67
 | 
   493         IF "issue_row"."accepted" ISNULL THEN
 | 
| 
jbe@67
 | 
   494           IF EXISTS (
 | 
| 
jbe@67
 | 
   495             SELECT NULL FROM "initiative"
 | 
| 
jbe@67
 | 
   496             WHERE "issue_id" = "issue_id_p"
 | 
| 
jbe@67
 | 
   497             AND "supporter_count" > 0
 | 
| 
jbe@67
 | 
   498             AND "supporter_count" * "policy_row"."issue_quorum_den"
 | 
| 
jbe@67
 | 
   499             >= "issue_row"."population" * "policy_row"."issue_quorum_num"
 | 
| 
jbe@67
 | 
   500           ) THEN
 | 
| 
jbe@67
 | 
   501             -- accept issues, if supporter count is high enough
 | 
| 
jbe@67
 | 
   502             PERFORM "set_snapshot_event"("issue_id_p", 'end_of_admission');
 | 
| 
jbe@67
 | 
   503             "issue_row"."accepted" = now();  -- NOTE: "issue_row" used later
 | 
| 
jbe@67
 | 
   504             UPDATE "issue" SET "accepted" = "issue_row"."accepted"
 | 
| 
jbe@67
 | 
   505               WHERE "id" = "issue_row"."id";
 | 
| 
jbe@67
 | 
   506           ELSIF
 | 
| 
jbe@67
 | 
   507             now() >= "issue_row"."created" + "issue_row"."admission_time"
 | 
| 
jbe@67
 | 
   508           THEN
 | 
| 
jbe@67
 | 
   509             -- close issues, if admission time has expired
 | 
| 
jbe@67
 | 
   510             PERFORM "set_snapshot_event"("issue_id_p", 'end_of_admission');
 | 
| 
jbe@67
 | 
   511             UPDATE "issue" SET "closed" = now()
 | 
| 
jbe@67
 | 
   512               WHERE "id" = "issue_row"."id";
 | 
| 
jbe@67
 | 
   513           END IF;
 | 
| 
jbe@67
 | 
   514         END IF;
 | 
| 
jbe@67
 | 
   515         -- eventually half freeze issues:
 | 
| 
jbe@67
 | 
   516         IF
 | 
| 
jbe@67
 | 
   517           -- NOTE: issue can't be closed at this point, if it has been accepted
 | 
| 
jbe@67
 | 
   518           "issue_row"."accepted" NOTNULL AND
 | 
| 
jbe@67
 | 
   519           "issue_row"."half_frozen" ISNULL
 | 
| 
jbe@67
 | 
   520         THEN
 | 
| 
jbe@67
 | 
   521           SELECT
 | 
| 
jbe@67
 | 
   522             CASE
 | 
| 
jbe@67
 | 
   523               WHEN "vote_now" * 2 > "issue_row"."population" THEN
 | 
| 
jbe@67
 | 
   524                 TRUE
 | 
| 
jbe@67
 | 
   525               WHEN "vote_later" * 2 > "issue_row"."population" THEN
 | 
| 
jbe@67
 | 
   526                 FALSE
 | 
| 
jbe@67
 | 
   527               ELSE NULL
 | 
| 
jbe@67
 | 
   528             END
 | 
| 
jbe@67
 | 
   529             INTO "voting_requested_v"
 | 
| 
jbe@67
 | 
   530             FROM "issue" WHERE "id" = "issue_id_p";
 | 
| 
jbe@67
 | 
   531           IF
 | 
| 
jbe@67
 | 
   532             "voting_requested_v" OR (
 | 
| 
jbe@67
 | 
   533               "voting_requested_v" ISNULL AND
 | 
| 
jbe@67
 | 
   534               now() >= "issue_row"."accepted" + "issue_row"."discussion_time"
 | 
| 
jbe@67
 | 
   535             )
 | 
| 
jbe@67
 | 
   536           THEN
 | 
| 
jbe@67
 | 
   537             PERFORM "set_snapshot_event"("issue_id_p", 'half_freeze');
 | 
| 
jbe@67
 | 
   538             "issue_row"."half_frozen" = now();  -- NOTE: "issue_row" used later
 | 
| 
jbe@67
 | 
   539             UPDATE "issue" SET "half_frozen" = "issue_row"."half_frozen"
 | 
| 
jbe@67
 | 
   540               WHERE "id" = "issue_row"."id";
 | 
| 
jbe@67
 | 
   541           END IF;
 | 
| 
jbe@67
 | 
   542         END IF;
 | 
| 
jbe@67
 | 
   543         -- close issues after some time, if all initiatives have been revoked:
 | 
| 
jbe@67
 | 
   544         IF
 | 
| 
jbe@67
 | 
   545           "issue_row"."closed" ISNULL AND
 | 
| 
jbe@67
 | 
   546           NOT EXISTS (
 | 
| 
jbe@67
 | 
   547             -- all initiatives are revoked
 | 
| 
jbe@67
 | 
   548             SELECT NULL FROM "initiative"
 | 
| 
jbe@67
 | 
   549             WHERE "issue_id" = "issue_id_p" AND "revoked" ISNULL
 | 
| 
jbe@67
 | 
   550           ) AND (
 | 
| 
jbe@67
 | 
   551             NOT EXISTS (
 | 
| 
jbe@67
 | 
   552               -- and no initiatives have been revoked lately
 | 
| 
jbe@67
 | 
   553               SELECT NULL FROM "initiative"
 | 
| 
jbe@67
 | 
   554               WHERE "issue_id" = "issue_id_p"
 | 
| 
jbe@67
 | 
   555               AND now() < "revoked" + "issue_row"."verification_time"
 | 
| 
jbe@67
 | 
   556             ) OR (
 | 
| 
jbe@67
 | 
   557               -- or verification time has elapsed
 | 
| 
jbe@67
 | 
   558               "issue_row"."half_frozen" NOTNULL AND
 | 
| 
jbe@67
 | 
   559               "issue_row"."fully_frozen" ISNULL AND
 | 
| 
jbe@67
 | 
   560               now() >= "issue_row"."half_frozen" + "issue_row"."verification_time"
 | 
| 
jbe@67
 | 
   561             )
 | 
| 
jbe@67
 | 
   562           )
 | 
| 
jbe@67
 | 
   563         THEN
 | 
| 
jbe@67
 | 
   564           "issue_row"."closed" = now();  -- NOTE: "issue_row" used later
 | 
| 
jbe@67
 | 
   565           UPDATE "issue" SET "closed" = "issue_row"."closed"
 | 
| 
jbe@67
 | 
   566             WHERE "id" = "issue_row"."id";
 | 
| 
jbe@67
 | 
   567         END IF;
 | 
| 
jbe@67
 | 
   568         -- fully freeze issue after verification time:
 | 
| 
jbe@67
 | 
   569         IF
 | 
| 
jbe@67
 | 
   570           "issue_row"."half_frozen" NOTNULL AND
 | 
| 
jbe@67
 | 
   571           "issue_row"."fully_frozen" ISNULL AND
 | 
| 
jbe@67
 | 
   572           "issue_row"."closed" ISNULL AND
 | 
| 
jbe@67
 | 
   573           now() >= "issue_row"."half_frozen" + "issue_row"."verification_time"
 | 
| 
jbe@67
 | 
   574         THEN
 | 
| 
jbe@67
 | 
   575           PERFORM "freeze_after_snapshot"("issue_id_p");
 | 
| 
jbe@67
 | 
   576           -- NOTE: "issue" might change, thus "issue_row" has to be updated below
 | 
| 
jbe@67
 | 
   577         END IF;
 | 
| 
jbe@67
 | 
   578         SELECT * INTO "issue_row" FROM "issue" WHERE "id" = "issue_id_p";
 | 
| 
jbe@67
 | 
   579         -- close issue by calling close_voting(...) after voting time:
 | 
| 
jbe@67
 | 
   580         IF
 | 
| 
jbe@67
 | 
   581           "issue_row"."closed" ISNULL AND
 | 
| 
jbe@67
 | 
   582           "issue_row"."fully_frozen" NOTNULL AND
 | 
| 
jbe@67
 | 
   583           now() >= "issue_row"."fully_frozen" + "issue_row"."voting_time"
 | 
| 
jbe@67
 | 
   584         THEN
 | 
| 
jbe@67
 | 
   585           PERFORM "close_voting"("issue_id_p");
 | 
| 
jbe@67
 | 
   586         END IF;
 | 
| 
jbe@67
 | 
   587       END IF;
 | 
| 
jbe@67
 | 
   588       RETURN;
 | 
| 
jbe@67
 | 
   589     END;
 | 
| 
jbe@67
 | 
   590   $$;
 | 
| 
jbe@67
 | 
   591 
 | 
| 
jbe@67
 | 
   592 
 | 
| 
jbe@67
 | 
   593 DROP FUNCTION "global_lock"();
 | 
| 
jbe@67
 | 
   594 
 | 
| 
jbe@67
 | 
   595 
 | 
| 
jbe@67
 | 
   596 COMMIT;
 |