liquid_feedback_core

view update/core-update.v3.0.5-v3.1.0.sql @ 453:fb7ccc4933a8

Update script for v3.1.0
author jbe
date Thu Dec 03 22:09:25 2015 +0100 (2015-12-03)
parents
children 63af9100628c
line source
1 BEGIN;
3 CREATE OR REPLACE VIEW "liquid_feedback_version" AS
4 SELECT * FROM (VALUES ('3.1.0', 3, 1, 0))
5 AS "subquery"("string", "major", "minor", "revision");
7 ALTER TABLE "member" DROP CONSTRAINT "authority_requires_uid_and_vice_versa";
8 ALTER TABLE "member" ADD CONSTRAINT "authority_requires_uid_and_vice_versa" CHECK (
9 ("authority" NOTNULL) = ("authority_uid" NOTNULL) );
11 DROP TABLE "member_application";
12 DROP TYPE "application_access_level";
14 ALTER TABLE "policy" ADD COLUMN "min_admission_time" INTERVAL DEFAULT '0';
15 ALTER TABLE "policy" ALTER COLUMN "min_admission_time" DROP DEFAULT;
16 ALTER TABLE "policy" RENAME COLUMN "admission_time" TO "max_admission_time";
18 ALTER TABLE "policy" DROP CONSTRAINT "timing";
19 ALTER TABLE "policy" ADD CONSTRAINT "timing" CHECK (
20 ( "polling" = FALSE AND
21 "min_admission_time" NOTNULL AND "max_admission_time" NOTNULL AND
22 "discussion_time" NOTNULL AND
23 "verification_time" NOTNULL AND
24 "voting_time" NOTNULL ) OR
25 ( "polling" = TRUE AND
26 "min_admission_time" ISNULL AND "max_admission_time" ISNULL AND
27 "discussion_time" NOTNULL AND
28 "verification_time" NOTNULL AND
29 "voting_time" NOTNULL ) OR
30 ( "polling" = TRUE AND
31 "min_admission_time" ISNULL AND "max_admission_time" ISNULL AND
32 "discussion_time" ISNULL AND
33 "verification_time" ISNULL AND
34 "voting_time" ISNULL ) );
36 ALTER TABLE "policy" DROP CONSTRAINT "issue_quorum_if_and_only_if_not_polling";
37 ALTER TABLE "policy" ADD CONSTRAINT "issue_quorum_if_and_only_if_not_polling" CHECK (
38 "polling" = ("issue_quorum_num" ISNULL) AND
39 "polling" = ("issue_quorum_den" ISNULL) );
41 COMMENT ON COLUMN "policy"."polling" IS 'TRUE = special policy for non-user-generated issues without issue quorum, where certain initiatives (those having the "polling" flag set) do not need to pass the initiative quorum; "min_admission_time" and "max_admission_time" MUST be set to NULL, the other timings may be set to NULL altogether, allowing individual timing for those issues';
42 COMMENT ON COLUMN "policy"."min_admission_time" IS 'Minimum duration of issue state ''admission''; Minimum time an issue stays open';
44 ALTER TABLE "issue" ADD COLUMN "min_admission_time" INTERVAL DEFAULT '0';
45 ALTER TABLE "issue" ALTER COLUMN "min_admission_time" DROP DEFAULT;
46 ALTER TABLE "issue" RENAME COLUMN "admission_time" TO "max_admission_time";
48 ALTER TABLE "issue" DROP CONSTRAINT "admission_time_not_null_unless_instantly_accepted";
49 ALTER TABLE "issue" ADD CONSTRAINT "admission_time_not_null_unless_instantly_accepted" CHECK (
50 ("min_admission_time" NOTNULL) = ("max_admission_time" NOTNULL) AND
51 ("min_admission_time" NOTNULL OR ("accepted" NOTNULL AND "accepted" = "created")) );
53 ALTER TABLE "issue" DROP CONSTRAINT "set_both_or_none_of_snapshot_and_latest_snapshot_event";
54 ALTER TABLE "issue" ADD CONSTRAINT "set_both_or_none_of_snapshot_and_latest_snapshot_event" CHECK (
55 (("snapshot" NOTNULL) = ("latest_snapshot_event" NOTNULL)) );
57 COMMENT ON COLUMN "issue"."closed" IS 'Point in time, when "max_admission_time" or "voting_time" have elapsed, and issue is no longer active; Frontends must ensure that for closed issues additionally to the restrictions for half_frozen and fully_frozen issues a) no voter is added or removed to/from the direct_voter table, b) no votes are added, modified or removed.';
58 COMMENT ON COLUMN "issue"."min_admission_time" IS 'Copied from "policy" table at creation of issue';
60 DROP TRIGGER "update_text_search_data" ON "initiative";
61 ALTER TABLE "initiative" DROP COLUMN "discussion_url";
63 ALTER TABLE "initiative" DROP CONSTRAINT "all_or_none_of_revoked_and_revoked_by_member_id_must_be_null";
64 ALTER TABLE "initiative" ADD CONSTRAINT "all_or_none_of_revoked_and_revoked_by_member_id_must_be_null" CHECK (
65 ("revoked" NOTNULL) = ("revoked_by_member_id" NOTNULL) );
67 CREATE TRIGGER "update_text_search_data"
68 BEFORE INSERT OR UPDATE ON "initiative"
69 FOR EACH ROW EXECUTE PROCEDURE
70 tsvector_update_trigger('text_search_data', 'pg_catalog.simple', "name");
72 ALTER TABLE "event" DROP CONSTRAINT "null_constraints_for_issue_state_changed";
73 ALTER TABLE "event" DROP CONSTRAINT "null_constraints_for_initiative_creation_or_revocation_or_new_draft";
74 ALTER TABLE "event" DROP CONSTRAINT "null_constraints_for_suggestion_creation";
76 ALTER TABLE "event" ADD CONSTRAINT "null_constr_for_issue_state_changed" CHECK (
77 "event" != 'issue_state_changed' OR (
78 "member_id" ISNULL AND
79 "issue_id" NOTNULL AND
80 "state" NOTNULL AND
81 "initiative_id" ISNULL AND
82 "draft_id" ISNULL AND
83 "suggestion_id" ISNULL ) );
84 ALTER TABLE "event" ADD CONSTRAINT "null_constr_for_initiative_creation_or_revocation_or_new_draft" CHECK (
85 "event" NOT IN (
86 'initiative_created_in_new_issue',
87 'initiative_created_in_existing_issue',
88 'initiative_revoked',
89 'new_draft_created'
90 ) OR (
91 "member_id" NOTNULL AND
92 "issue_id" NOTNULL AND
93 "state" NOTNULL AND
94 "initiative_id" NOTNULL AND
95 "draft_id" NOTNULL AND
96 "suggestion_id" ISNULL ) );
97 ALTER TABLE "event" ADD CONSTRAINT "null_constr_for_suggestion_creation" CHECK (
98 "event" != 'suggestion_created' OR (
99 "member_id" NOTNULL AND
100 "issue_id" NOTNULL AND
101 "state" NOTNULL AND
102 "initiative_id" NOTNULL AND
103 "draft_id" ISNULL AND
104 "suggestion_id" NOTNULL ) );
106 CREATE OR REPLACE FUNCTION "copy_timings_trigger"()
107 RETURNS TRIGGER
108 LANGUAGE 'plpgsql' VOLATILE AS $$
109 DECLARE
110 "policy_row" "policy"%ROWTYPE;
111 BEGIN
112 SELECT * INTO "policy_row" FROM "policy"
113 WHERE "id" = NEW."policy_id";
114 IF NEW."min_admission_time" ISNULL THEN
115 NEW."min_admission_time" := "policy_row"."min_admission_time";
116 END IF;
117 IF NEW."max_admission_time" ISNULL THEN
118 NEW."max_admission_time" := "policy_row"."max_admission_time";
119 END IF;
120 IF NEW."discussion_time" ISNULL THEN
121 NEW."discussion_time" := "policy_row"."discussion_time";
122 END IF;
123 IF NEW."verification_time" ISNULL THEN
124 NEW."verification_time" := "policy_row"."verification_time";
125 END IF;
126 IF NEW."voting_time" ISNULL THEN
127 NEW."voting_time" := "policy_row"."voting_time";
128 END IF;
129 RETURN NEW;
130 END;
131 $$;
133 CREATE OR REPLACE FUNCTION "check_issue"
134 ( "issue_id_p" "issue"."id"%TYPE,
135 "persist" "check_issue_persistence" )
136 RETURNS "check_issue_persistence"
137 LANGUAGE 'plpgsql' VOLATILE AS $$
138 DECLARE
139 "issue_row" "issue"%ROWTYPE;
140 "policy_row" "policy"%ROWTYPE;
141 "initiative_row" "initiative"%ROWTYPE;
142 "state_v" "issue_state";
143 BEGIN
144 PERFORM "require_transaction_isolation"();
145 IF "persist" ISNULL THEN
146 SELECT * INTO "issue_row" FROM "issue" WHERE "id" = "issue_id_p"
147 FOR UPDATE;
148 IF "issue_row"."closed" NOTNULL THEN
149 RETURN NULL;
150 END IF;
151 "persist"."state" := "issue_row"."state";
152 IF
153 ( "issue_row"."state" = 'admission' AND now() >=
154 "issue_row"."created" + "issue_row"."max_admission_time" ) OR
155 ( "issue_row"."state" = 'discussion' AND now() >=
156 "issue_row"."accepted" + "issue_row"."discussion_time" ) OR
157 ( "issue_row"."state" = 'verification' AND now() >=
158 "issue_row"."half_frozen" + "issue_row"."verification_time" ) OR
159 ( "issue_row"."state" = 'voting' AND now() >=
160 "issue_row"."fully_frozen" + "issue_row"."voting_time" )
161 THEN
162 "persist"."phase_finished" := TRUE;
163 ELSE
164 "persist"."phase_finished" := FALSE;
165 END IF;
166 IF
167 NOT EXISTS (
168 -- all initiatives are revoked
169 SELECT NULL FROM "initiative"
170 WHERE "issue_id" = "issue_id_p" AND "revoked" ISNULL
171 ) AND (
172 -- and issue has not been accepted yet
173 "persist"."state" = 'admission' OR
174 -- or verification time has elapsed
175 ( "persist"."state" = 'verification' AND
176 "persist"."phase_finished" ) OR
177 -- or no initiatives have been revoked lately
178 NOT EXISTS (
179 SELECT NULL FROM "initiative"
180 WHERE "issue_id" = "issue_id_p"
181 AND now() < "revoked" + "issue_row"."verification_time"
182 )
183 )
184 THEN
185 "persist"."issue_revoked" := TRUE;
186 ELSE
187 "persist"."issue_revoked" := FALSE;
188 END IF;
189 IF "persist"."phase_finished" OR "persist"."issue_revoked" THEN
190 UPDATE "issue" SET "phase_finished" = now()
191 WHERE "id" = "issue_row"."id";
192 RETURN "persist";
193 ELSIF
194 "persist"."state" IN ('admission', 'discussion', 'verification')
195 THEN
196 RETURN "persist";
197 ELSE
198 RETURN NULL;
199 END IF;
200 END IF;
201 IF
202 "persist"."state" IN ('admission', 'discussion', 'verification') AND
203 coalesce("persist"."snapshot_created", FALSE) = FALSE
204 THEN
205 PERFORM "create_snapshot"("issue_id_p");
206 "persist"."snapshot_created" = TRUE;
207 IF "persist"."phase_finished" THEN
208 IF "persist"."state" = 'admission' THEN
209 PERFORM "set_snapshot_event"("issue_id_p", 'end_of_admission');
210 ELSIF "persist"."state" = 'discussion' THEN
211 PERFORM "set_snapshot_event"("issue_id_p", 'half_freeze');
212 ELSIF "persist"."state" = 'verification' THEN
213 PERFORM "set_snapshot_event"("issue_id_p", 'full_freeze');
214 SELECT * INTO "issue_row" FROM "issue" WHERE "id" = "issue_id_p";
215 SELECT * INTO "policy_row" FROM "policy"
216 WHERE "id" = "issue_row"."policy_id";
217 FOR "initiative_row" IN
218 SELECT * FROM "initiative"
219 WHERE "issue_id" = "issue_id_p" AND "revoked" ISNULL
220 FOR UPDATE
221 LOOP
222 IF
223 "initiative_row"."polling" OR (
224 "initiative_row"."satisfied_supporter_count" > 0 AND
225 "initiative_row"."satisfied_supporter_count" *
226 "policy_row"."initiative_quorum_den" >=
227 "issue_row"."population" * "policy_row"."initiative_quorum_num"
228 )
229 THEN
230 UPDATE "initiative" SET "admitted" = TRUE
231 WHERE "id" = "initiative_row"."id";
232 ELSE
233 UPDATE "initiative" SET "admitted" = FALSE
234 WHERE "id" = "initiative_row"."id";
235 END IF;
236 END LOOP;
237 END IF;
238 END IF;
239 RETURN "persist";
240 END IF;
241 IF
242 "persist"."state" IN ('admission', 'discussion', 'verification') AND
243 coalesce("persist"."harmonic_weights_set", FALSE) = FALSE
244 THEN
245 PERFORM "set_harmonic_initiative_weights"("issue_id_p");
246 "persist"."harmonic_weights_set" = TRUE;
247 IF
248 "persist"."phase_finished" OR
249 "persist"."issue_revoked" OR
250 "persist"."state" = 'admission'
251 THEN
252 RETURN "persist";
253 ELSE
254 RETURN NULL;
255 END IF;
256 END IF;
257 IF "persist"."issue_revoked" THEN
258 IF "persist"."state" = 'admission' THEN
259 "state_v" := 'canceled_revoked_before_accepted';
260 ELSIF "persist"."state" = 'discussion' THEN
261 "state_v" := 'canceled_after_revocation_during_discussion';
262 ELSIF "persist"."state" = 'verification' THEN
263 "state_v" := 'canceled_after_revocation_during_verification';
264 END IF;
265 UPDATE "issue" SET
266 "state" = "state_v",
267 "closed" = "phase_finished",
268 "phase_finished" = NULL
269 WHERE "id" = "issue_id_p";
270 RETURN NULL;
271 END IF;
272 IF "persist"."state" = 'admission' THEN
273 SELECT * INTO "issue_row" FROM "issue" WHERE "id" = "issue_id_p"
274 FOR UPDATE;
275 SELECT * INTO "policy_row"
276 FROM "policy" WHERE "id" = "issue_row"."policy_id";
277 IF
278 ( now() >=
279 "issue_row"."created" + "issue_row"."min_admission_time" ) AND
280 EXISTS (
281 SELECT NULL FROM "initiative"
282 WHERE "issue_id" = "issue_id_p"
283 AND "supporter_count" > 0
284 AND "supporter_count" * "policy_row"."issue_quorum_den"
285 >= "issue_row"."population" * "policy_row"."issue_quorum_num"
286 )
287 THEN
288 UPDATE "issue" SET
289 "state" = 'discussion',
290 "accepted" = coalesce("phase_finished", now()),
291 "phase_finished" = NULL
292 WHERE "id" = "issue_id_p";
293 ELSIF "issue_row"."phase_finished" NOTNULL THEN
294 UPDATE "issue" SET
295 "state" = 'canceled_issue_not_accepted',
296 "closed" = "phase_finished",
297 "phase_finished" = NULL
298 WHERE "id" = "issue_id_p";
299 END IF;
300 RETURN NULL;
301 END IF;
302 IF "persist"."phase_finished" THEN
303 IF "persist"."state" = 'discussion' THEN
304 UPDATE "issue" SET
305 "state" = 'verification',
306 "half_frozen" = "phase_finished",
307 "phase_finished" = NULL
308 WHERE "id" = "issue_id_p";
309 RETURN NULL;
310 END IF;
311 IF "persist"."state" = 'verification' THEN
312 SELECT * INTO "issue_row" FROM "issue" WHERE "id" = "issue_id_p"
313 FOR UPDATE;
314 SELECT * INTO "policy_row" FROM "policy"
315 WHERE "id" = "issue_row"."policy_id";
316 IF EXISTS (
317 SELECT NULL FROM "initiative"
318 WHERE "issue_id" = "issue_id_p" AND "admitted" = TRUE
319 ) THEN
320 UPDATE "issue" SET
321 "state" = 'voting',
322 "fully_frozen" = "phase_finished",
323 "phase_finished" = NULL
324 WHERE "id" = "issue_id_p";
325 ELSE
326 UPDATE "issue" SET
327 "state" = 'canceled_no_initiative_admitted',
328 "fully_frozen" = "phase_finished",
329 "closed" = "phase_finished",
330 "phase_finished" = NULL
331 WHERE "id" = "issue_id_p";
332 -- NOTE: The following DELETE statements have effect only when
333 -- issue state has been manipulated
334 DELETE FROM "direct_voter" WHERE "issue_id" = "issue_id_p";
335 DELETE FROM "delegating_voter" WHERE "issue_id" = "issue_id_p";
336 DELETE FROM "battle" WHERE "issue_id" = "issue_id_p";
337 END IF;
338 RETURN NULL;
339 END IF;
340 IF "persist"."state" = 'voting' THEN
341 IF coalesce("persist"."closed_voting", FALSE) = FALSE THEN
342 PERFORM "close_voting"("issue_id_p");
343 "persist"."closed_voting" = TRUE;
344 RETURN "persist";
345 END IF;
346 PERFORM "calculate_ranks"("issue_id_p");
347 RETURN NULL;
348 END IF;
349 END IF;
350 RAISE WARNING 'should not happen';
351 RETURN NULL;
352 END;
353 $$;
355 COMMIT;

Impressum / About Us