liquid_feedback_core

view update/core-update.v1.2.4-v1.2.5.sql @ 364:28f860d5dfb4

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

Impressum / About Us