rev |
line source |
jbe@536
|
1 ALTER TYPE "event_type" ADD VALUE IF NOT EXISTS 'unit_created';
|
jbe@536
|
2 ALTER TYPE "event_type" ADD VALUE IF NOT EXISTS 'unit_updated';
|
jbe@539
|
3 ALTER TYPE "event_type" ADD VALUE IF NOT EXISTS 'area_created';
|
jbe@539
|
4 ALTER TYPE "event_type" ADD VALUE IF NOT EXISTS 'area_updated';
|
jbe@536
|
5 ALTER TYPE "event_type" ADD VALUE IF NOT EXISTS 'policy_created';
|
jbe@536
|
6 ALTER TYPE "event_type" ADD VALUE IF NOT EXISTS 'policy_updated';
|
jbe@554
|
7 ALTER TYPE "event_type" ADD VALUE IF NOT EXISTS 'suggestion_deleted';
|
jbe@532
|
8 ALTER TYPE "event_type" ADD VALUE IF NOT EXISTS 'member_activated';
|
jbe@554
|
9 ALTER TYPE "event_type" ADD VALUE IF NOT EXISTS 'member_deleted';
|
jbe@532
|
10 ALTER TYPE "event_type" ADD VALUE IF NOT EXISTS 'member_active';
|
jbe@532
|
11 ALTER TYPE "event_type" ADD VALUE IF NOT EXISTS 'member_name_updated';
|
jbe@532
|
12 ALTER TYPE "event_type" ADD VALUE IF NOT EXISTS 'member_profile_updated';
|
jbe@532
|
13 ALTER TYPE "event_type" ADD VALUE IF NOT EXISTS 'member_image_updated';
|
jbe@532
|
14 ALTER TYPE "event_type" ADD VALUE IF NOT EXISTS 'interest';
|
jbe@532
|
15 ALTER TYPE "event_type" ADD VALUE IF NOT EXISTS 'initiator';
|
jbe@532
|
16 ALTER TYPE "event_type" ADD VALUE IF NOT EXISTS 'support';
|
jbe@532
|
17 ALTER TYPE "event_type" ADD VALUE IF NOT EXISTS 'support_updated';
|
jbe@532
|
18 ALTER TYPE "event_type" ADD VALUE IF NOT EXISTS 'suggestion_rated';
|
jbe@532
|
19 ALTER TYPE "event_type" ADD VALUE IF NOT EXISTS 'delegation';
|
jbe@532
|
20 ALTER TYPE "event_type" ADD VALUE IF NOT EXISTS 'contact';
|
jbe@532
|
21
|
jbe@532
|
22
|
jbe@532
|
23 BEGIN;
|
jbe@532
|
24
|
jbe@532
|
25
|
jbe@532
|
26 CREATE OR REPLACE VIEW "liquid_feedback_version" AS
|
jbe@532
|
27 SELECT * FROM (VALUES ('4.0-dev', 4, 0, -1))
|
jbe@532
|
28 AS "subquery"("string", "major", "minor", "revision");
|
jbe@532
|
29
|
jbe@532
|
30
|
jbe@532
|
31 ALTER TABLE "system_setting" ADD COLUMN "snapshot_retention" INTERVAL;
|
jbe@532
|
32
|
jbe@532
|
33 COMMENT ON COLUMN "system_setting"."snapshot_retention" IS 'Unreferenced snapshots are retained for the given period of time after creation; set to NULL for infinite retention.';
|
jbe@552
|
34
|
jbe@552
|
35
|
jbe@557
|
36 CREATE TABLE "verification" (
|
jbe@557
|
37 "id" SERIAL8 PRIMARY KEY,
|
jbe@557
|
38 "requested" TIMESTAMPTZ,
|
jbe@557
|
39 "request_origin" JSONB,
|
jbe@557
|
40 "request_data" JSONB,
|
jbe@557
|
41 "verified" TIMESTAMPTZ,
|
jbe@557
|
42 "verification_origin" JSONB,
|
jbe@557
|
43 "verification_data" JSONB,
|
jbe@557
|
44 "denied" TIMESTAMPTZ,
|
jbe@557
|
45 "member_id" INT4 REFERENCES "member" ("id") ON DELETE RESTRICT ON UPDATE CASCADE,
|
jbe@557
|
46 "comment" TEXT,
|
jbe@557
|
47 CONSTRAINT "verified_and_denied_conflict" CHECK (
|
jbe@557
|
48 "verified" ISNULL OR "denied" ISNULL ) );
|
jbe@557
|
49 CREATE INDEX "verification_requested_idx" ON "verification" ("requested");
|
jbe@557
|
50 CREATE INDEX "verification_open_request_idx" ON "verification" ("requested") WHERE "verified" ISNULL AND "denied" ISNULL;
|
jbe@557
|
51 CREATE INDEX "verification_verified_idx" ON "verification" ("verified");
|
jbe@557
|
52 CREATE INDEX "verification_denied_idx" ON "verification" ("denied");
|
jbe@557
|
53 CREATE INDEX "verification_member_id_idx" ON "verification" ("member_id");
|
jbe@557
|
54
|
jbe@557
|
55 COMMENT ON TABLE "verification" IS 'Request to verify a participant';
|
jbe@557
|
56
|
jbe@557
|
57 COMMENT ON COLUMN "verification"."requested" IS 'Timestamp when request for verification has been submitted';
|
jbe@557
|
58 COMMENT ON COLUMN "verification"."request_origin" IS 'JSON data containing information about the origin of the request (e.g. IP address or hostname)';
|
jbe@557
|
59 COMMENT ON COLUMN "verification"."request_data" IS 'JSON data containing information about the entity to be verified (e.g. real name, address, etc.)';
|
jbe@557
|
60 COMMENT ON COLUMN "verification"."verified" IS 'Timestamp when request for verification has been accepted by authority';
|
jbe@557
|
61 COMMENT ON COLUMN "verification"."verification_origin" IS 'JSON data containing information about the authority or operator who accepted or denied the request';
|
jbe@557
|
62 COMMENT ON COLUMN "verification"."verification_data" IS 'JSON data containing additional verified data, but all public information shall be copied to "member"."identification", "member"."verification" and/or "member"."name" if applicable for setup';
|
jbe@557
|
63 COMMENT ON COLUMN "verification"."denied" IS 'Timestamp when request for verification has been denied by authority';
|
jbe@557
|
64 COMMENT ON COLUMN "verification"."member_id" IS 'Timestamp when request for verification has been denied by authority';
|
jbe@557
|
65 COMMENT ON COLUMN "verification"."comment" IS 'Administrative comment';
|
jbe@557
|
66
|
jbe@557
|
67
|
jbe@552
|
68 ALTER TABLE "member" ADD COLUMN "deleted" TIMESTAMPTZ;
|
jbe@552
|
69 ALTER TABLE "member" ADD CONSTRAINT "deleted_requires_locked"
|
jbe@552
|
70 CHECK ("deleted" ISNULL OR "locked" = TRUE);
|
jbe@532
|
71
|
jbe@552
|
72 COMMENT ON COLUMN "member"."deleted" IS 'Timestamp of deletion (set by "delete_member" function)';
|
jbe@552
|
73
|
jbe@532
|
74
|
jbe@544
|
75 CREATE TABLE "member_settings" (
|
jbe@544
|
76 "member_id" INT4 PRIMARY KEY REFERENCES "member" ("id") ON DELETE CASCADE ON UPDATE CASCADE,
|
jbe@544
|
77 "settings" JSONB NOT NULL CHECK (jsonb_typeof("settings") = 'object') );
|
jbe@544
|
78
|
jbe@544
|
79 COMMENT ON TABLE "member_settings" IS 'Stores a JSON document for each member containing optional (additional) settings for the respective member';
|
jbe@544
|
80
|
jbe@544
|
81
|
jbe@544
|
82 CREATE TABLE "member_useterms" (
|
jbe@559
|
83 "id" SERIAL8 PRIMARY KEY,
|
jbe@559
|
84 "member_id" INT4 NOT NULL REFERENCES "member" ("id") ON DELETE CASCADE ON UPDATE CASCADE,
|
jbe@558
|
85 "accepted" TIMESTAMPTZ NOT NULL DEFAULT now(),
|
jbe@544
|
86 "contract_identifier" TEXT NOT NULL );
|
jbe@544
|
87
|
jbe@544
|
88 COMMENT ON TABLE "member_useterms" IS 'Keeps record of accepted terms of use; may contain multiple rows per member';
|
jbe@544
|
89
|
jbe@544
|
90 COMMENT ON COLUMN "member_useterms"."accepted" IS 'Point in time when user accepted the terms of use';
|
jbe@544
|
91 COMMENT ON COLUMN "member_useterms"."contract_identifier" IS 'String identifier to denote the accepted terms of use, including their version or revision';
|
jbe@544
|
92
|
jbe@544
|
93
|
jbe@532
|
94 CREATE TABLE "member_profile" (
|
jbe@532
|
95 "member_id" INT4 PRIMARY KEY REFERENCES "member" ("id") ON DELETE CASCADE ON UPDATE CASCADE,
|
jbe@532
|
96 "formatting_engine" TEXT,
|
jbe@532
|
97 "statement" TEXT,
|
jbe@544
|
98 "profile" JSONB NOT NULL DEFAULT '{}' CHECK (jsonb_typeof("profile") = 'object'),
|
jbe@532
|
99 "profile_text_data" TEXT,
|
jbe@532
|
100 "text_search_data" TSVECTOR );
|
jbe@532
|
101 CREATE INDEX "member_profile_text_search_data_idx" ON "member_profile" USING gin ("text_search_data");
|
jbe@532
|
102 CREATE TRIGGER "update_text_search_data"
|
jbe@532
|
103 BEFORE INSERT OR UPDATE ON "member_profile"
|
jbe@532
|
104 FOR EACH ROW EXECUTE PROCEDURE
|
jbe@532
|
105 tsvector_update_trigger('text_search_data', 'pg_catalog.simple',
|
jbe@532
|
106 'statement', 'profile_text_data');
|
jbe@532
|
107
|
jbe@532
|
108 COMMENT ON COLUMN "member_profile"."formatting_engine" IS 'Allows different formatting engines (i.e. wiki formats) to be used for "member_profile"."statement"';
|
jbe@532
|
109 COMMENT ON COLUMN "member_profile"."statement" IS 'Freely chosen text of the member for his/her profile';
|
jbe@532
|
110 COMMENT ON COLUMN "member_profile"."profile" IS 'Additional profile data as JSON document';
|
jbe@532
|
111 COMMENT ON COLUMN "member_profile"."profile_text_data" IS 'Text data from "profile" field for full text search';
|
jbe@532
|
112
|
jbe@532
|
113
|
jbe@532
|
114 INSERT INTO "member_profile"
|
jbe@532
|
115 ( "member_id", "formatting_engine", "statement", "profile")
|
jbe@532
|
116 SELECT
|
jbe@532
|
117 "id" AS "member_id",
|
jbe@532
|
118 "formatting_engine",
|
jbe@532
|
119 "statement",
|
jbe@532
|
120 json_build_object(
|
jbe@532
|
121 'organizational_unit', "organizational_unit",
|
jbe@532
|
122 'internal_posts', "internal_posts",
|
jbe@532
|
123 'realname', "realname",
|
jbe@532
|
124 'birthday', to_char("birthday", 'YYYY-MM-DD'),
|
jbe@532
|
125 'address', "address",
|
jbe@532
|
126 'email', "email",
|
jbe@532
|
127 'xmpp_address', "xmpp_address",
|
jbe@532
|
128 'website', "website",
|
jbe@532
|
129 'phone', "phone",
|
jbe@532
|
130 'mobile_phone', "mobile_phone",
|
jbe@532
|
131 'profession', "profession",
|
jbe@532
|
132 'external_memberships', "external_memberships",
|
jbe@532
|
133 'external_posts', "external_posts"
|
jbe@532
|
134 ) AS "profile"
|
jbe@532
|
135 FROM "member";
|
jbe@532
|
136
|
jbe@532
|
137 UPDATE "member_profile" SET "profile_text_data" =
|
jbe@532
|
138 coalesce(("profile"->>'organizational_unit') || ' ', '') ||
|
jbe@532
|
139 coalesce(("profile"->>'internal_posts') || ' ', '') ||
|
jbe@532
|
140 coalesce(("profile"->>'realname') || ' ', '') ||
|
jbe@532
|
141 coalesce(("profile"->>'birthday') || ' ', '') ||
|
jbe@532
|
142 coalesce(("profile"->>'address') || ' ', '') ||
|
jbe@532
|
143 coalesce(("profile"->>'email') || ' ', '') ||
|
jbe@532
|
144 coalesce(("profile"->>'xmpp_address') || ' ', '') ||
|
jbe@532
|
145 coalesce(("profile"->>'website') || ' ', '') ||
|
jbe@532
|
146 coalesce(("profile"->>'phone') || ' ', '') ||
|
jbe@532
|
147 coalesce(("profile"->>'mobile_phone') || ' ', '') ||
|
jbe@532
|
148 coalesce(("profile"->>'profession') || ' ', '') ||
|
jbe@532
|
149 coalesce(("profile"->>'external_memberships') || ' ', '') ||
|
jbe@532
|
150 coalesce(("profile"->>'external_posts') || ' ', '');
|
jbe@532
|
151
|
jbe@532
|
152
|
jbe@532
|
153 DROP VIEW "newsletter_to_send";
|
jbe@532
|
154 DROP VIEW "scheduled_notification_to_send";
|
jbe@532
|
155 DROP VIEW "member_to_notify";
|
jbe@532
|
156 DROP VIEW "member_eligible_to_be_notified";
|
jbe@532
|
157
|
jbe@532
|
158
|
jbe@532
|
159 ALTER TABLE "member" DROP COLUMN "organizational_unit";
|
jbe@532
|
160 ALTER TABLE "member" DROP COLUMN "internal_posts";
|
jbe@532
|
161 ALTER TABLE "member" DROP COLUMN "realname";
|
jbe@532
|
162 ALTER TABLE "member" DROP COLUMN "birthday";
|
jbe@532
|
163 ALTER TABLE "member" DROP COLUMN "address";
|
jbe@532
|
164 ALTER TABLE "member" DROP COLUMN "email";
|
jbe@532
|
165 ALTER TABLE "member" DROP COLUMN "xmpp_address";
|
jbe@532
|
166 ALTER TABLE "member" DROP COLUMN "website";
|
jbe@532
|
167 ALTER TABLE "member" DROP COLUMN "phone";
|
jbe@532
|
168 ALTER TABLE "member" DROP COLUMN "mobile_phone";
|
jbe@532
|
169 ALTER TABLE "member" DROP COLUMN "profession";
|
jbe@532
|
170 ALTER TABLE "member" DROP COLUMN "external_memberships";
|
jbe@532
|
171 ALTER TABLE "member" DROP COLUMN "external_posts";
|
jbe@532
|
172 ALTER TABLE "member" DROP COLUMN "formatting_engine";
|
jbe@532
|
173 ALTER TABLE "member" DROP COLUMN "statement";
|
jbe@532
|
174
|
jbe@532
|
175 ALTER TABLE "member" ADD COLUMN "location" JSONB;
|
jbe@532
|
176 COMMENT ON COLUMN "member"."location" IS 'Geographic location on earth as GeoJSON object';
|
jbe@532
|
177 CREATE INDEX "member_location_idx" ON "member" USING gist ((GeoJSON_to_ecluster("location")));
|
jbe@532
|
178
|
jbe@532
|
179 DROP TRIGGER "update_text_search_data" ON "member";
|
jbe@532
|
180 CREATE TRIGGER "update_text_search_data"
|
jbe@532
|
181 BEFORE INSERT OR UPDATE ON "member"
|
jbe@532
|
182 FOR EACH ROW EXECUTE PROCEDURE
|
jbe@532
|
183 tsvector_update_trigger('text_search_data', 'pg_catalog.simple',
|
jbe@532
|
184 "name", "identification");
|
jbe@532
|
185
|
jbe@532
|
186
|
jbe@532
|
187 CREATE VIEW "member_eligible_to_be_notified" AS
|
jbe@532
|
188 SELECT * FROM "member"
|
jbe@532
|
189 WHERE "activated" NOTNULL AND "locked" = FALSE;
|
jbe@532
|
190
|
jbe@532
|
191 COMMENT ON VIEW "member_eligible_to_be_notified" IS 'Filtered "member" table containing only activated and non-locked members (used as helper view for "member_to_notify" and "newsletter_to_send")';
|
jbe@532
|
192
|
jbe@532
|
193
|
jbe@532
|
194 CREATE VIEW "member_to_notify" AS
|
jbe@532
|
195 SELECT * FROM "member_eligible_to_be_notified"
|
jbe@532
|
196 WHERE "disable_notifications" = FALSE;
|
jbe@532
|
197
|
jbe@532
|
198 COMMENT ON VIEW "member_to_notify" IS 'Filtered "member" table containing only members that are eligible to and wish to receive notifications; NOTE: "notify_email" may still be NULL and might need to be checked by frontend (this allows other means of messaging)';
|
jbe@532
|
199
|
jbe@532
|
200
|
jbe@532
|
201 CREATE VIEW "scheduled_notification_to_send" AS
|
jbe@532
|
202 SELECT * FROM (
|
jbe@532
|
203 SELECT
|
jbe@532
|
204 "id" AS "recipient_id",
|
jbe@532
|
205 now() - CASE WHEN "notification_dow" ISNULL THEN
|
jbe@532
|
206 ( "notification_sent"::DATE + CASE
|
jbe@532
|
207 WHEN EXTRACT(HOUR FROM "notification_sent") < "notification_hour"
|
jbe@532
|
208 THEN 0 ELSE 1 END
|
jbe@532
|
209 )::TIMESTAMP + '1 hour'::INTERVAL * "notification_hour"
|
jbe@532
|
210 ELSE
|
jbe@532
|
211 ( "notification_sent"::DATE +
|
jbe@532
|
212 ( 7 + "notification_dow" -
|
jbe@532
|
213 EXTRACT(DOW FROM
|
jbe@532
|
214 ( "notification_sent"::DATE + CASE
|
jbe@532
|
215 WHEN EXTRACT(HOUR FROM "notification_sent") < "notification_hour"
|
jbe@532
|
216 THEN 0 ELSE 1 END
|
jbe@532
|
217 )::TIMESTAMP + '1 hour'::INTERVAL * "notification_hour"
|
jbe@532
|
218 )::INTEGER
|
jbe@532
|
219 ) % 7 +
|
jbe@532
|
220 CASE
|
jbe@532
|
221 WHEN EXTRACT(HOUR FROM "notification_sent") < "notification_hour"
|
jbe@532
|
222 THEN 0 ELSE 1
|
jbe@532
|
223 END
|
jbe@532
|
224 )::TIMESTAMP + '1 hour'::INTERVAL * "notification_hour"
|
jbe@532
|
225 END AS "pending"
|
jbe@532
|
226 FROM (
|
jbe@532
|
227 SELECT
|
jbe@532
|
228 "id",
|
jbe@532
|
229 COALESCE("notification_sent", "activated") AS "notification_sent",
|
jbe@532
|
230 "notification_dow",
|
jbe@532
|
231 "notification_hour"
|
jbe@532
|
232 FROM "member_to_notify"
|
jbe@532
|
233 WHERE "notification_hour" NOTNULL
|
jbe@532
|
234 ) AS "subquery1"
|
jbe@532
|
235 ) AS "subquery2"
|
jbe@532
|
236 WHERE "pending" > '0'::INTERVAL;
|
jbe@532
|
237
|
jbe@532
|
238 COMMENT ON VIEW "scheduled_notification_to_send" IS 'Set of members where a scheduled notification mail is pending';
|
jbe@532
|
239
|
jbe@532
|
240 COMMENT ON COLUMN "scheduled_notification_to_send"."recipient_id" IS '"id" of the member who needs to receive a notification mail';
|
jbe@532
|
241 COMMENT ON COLUMN "scheduled_notification_to_send"."pending" IS 'Duration for which the notification mail has already been pending';
|
jbe@532
|
242
|
jbe@532
|
243
|
jbe@532
|
244 CREATE VIEW "newsletter_to_send" AS
|
jbe@532
|
245 SELECT
|
jbe@532
|
246 "member"."id" AS "recipient_id",
|
jbe@532
|
247 "newsletter"."id" AS "newsletter_id",
|
jbe@532
|
248 "newsletter"."published"
|
jbe@532
|
249 FROM "newsletter" CROSS JOIN "member_eligible_to_be_notified" AS "member"
|
jbe@556
|
250 LEFT JOIN "privilege" ON
|
jbe@556
|
251 "privilege"."member_id" = "member"."id" AND
|
jbe@556
|
252 "privilege"."unit_id" = "newsletter"."unit_id" AND
|
jbe@556
|
253 "privilege"."voting_right" = TRUE
|
jbe@532
|
254 LEFT JOIN "subscription" ON
|
jbe@532
|
255 "subscription"."member_id" = "member"."id" AND
|
jbe@532
|
256 "subscription"."unit_id" = "newsletter"."unit_id"
|
jbe@532
|
257 WHERE "newsletter"."published" <= now()
|
jbe@532
|
258 AND "newsletter"."sent" ISNULL
|
jbe@532
|
259 AND (
|
jbe@532
|
260 "member"."disable_notifications" = FALSE OR
|
jbe@532
|
261 "newsletter"."include_all_members" = TRUE )
|
jbe@532
|
262 AND (
|
jbe@532
|
263 "newsletter"."unit_id" ISNULL OR
|
jbe@556
|
264 "privilege"."member_id" NOTNULL OR
|
jbe@532
|
265 "subscription"."member_id" NOTNULL );
|
jbe@532
|
266
|
jbe@532
|
267 COMMENT ON VIEW "newsletter_to_send" IS 'List of "newsletter_id"s for each member that are due to be sent out';
|
jbe@532
|
268
|
jbe@532
|
269 COMMENT ON COLUMN "newsletter"."published" IS 'Timestamp when the newsletter was supposed to be sent out (can be used for ordering)';
|
jbe@532
|
270
|
jbe@532
|
271
|
jbe@532
|
272 DROP VIEW "expired_session";
|
jbe@532
|
273 DROP TABLE "session";
|
jbe@532
|
274
|
jbe@532
|
275
|
jbe@532
|
276 CREATE TABLE "session" (
|
jbe@532
|
277 UNIQUE ("member_id", "id"), -- index needed for foreign-key on table "token"
|
jbe@532
|
278 "id" SERIAL8 PRIMARY KEY,
|
jbe@532
|
279 "ident" TEXT NOT NULL UNIQUE,
|
jbe@532
|
280 "additional_secret" TEXT,
|
jbe@532
|
281 "logout_token" TEXT,
|
jbe@532
|
282 "expiry" TIMESTAMPTZ NOT NULL DEFAULT now() + '24 hours',
|
jbe@532
|
283 "member_id" INT4 REFERENCES "member" ("id") ON DELETE SET NULL,
|
jbe@532
|
284 "authority" TEXT,
|
jbe@532
|
285 "authority_uid" TEXT,
|
jbe@532
|
286 "authority_login" TEXT,
|
jbe@532
|
287 "needs_delegation_check" BOOLEAN NOT NULL DEFAULT FALSE,
|
jbe@532
|
288 "lang" TEXT );
|
jbe@532
|
289 CREATE INDEX "session_expiry_idx" ON "session" ("expiry");
|
jbe@532
|
290
|
jbe@532
|
291 COMMENT ON TABLE "session" IS 'Sessions, i.e. for a web-frontend or API layer';
|
jbe@532
|
292
|
jbe@532
|
293 COMMENT ON COLUMN "session"."ident" IS 'Secret session identifier (i.e. random string)';
|
jbe@532
|
294 COMMENT ON COLUMN "session"."additional_secret" IS 'Additional field to store a secret, which can be used against CSRF attacks';
|
jbe@532
|
295 COMMENT ON COLUMN "session"."logout_token" IS 'Optional token to authorize logout through external component';
|
jbe@532
|
296 COMMENT ON COLUMN "session"."member_id" IS 'Reference to member, who is logged in';
|
jbe@532
|
297 COMMENT ON COLUMN "session"."authority" IS 'Temporary store for "member"."authority" during member account creation';
|
jbe@532
|
298 COMMENT ON COLUMN "session"."authority_uid" IS 'Temporary store for "member"."authority_uid" during member account creation';
|
jbe@532
|
299 COMMENT ON COLUMN "session"."authority_login" IS 'Temporary store for "member"."authority_login" during member account creation';
|
jbe@532
|
300 COMMENT ON COLUMN "session"."needs_delegation_check" IS 'Set to TRUE, if member must perform a delegation check to proceed with login; see column "last_delegation_check" in "member" table';
|
jbe@532
|
301 COMMENT ON COLUMN "session"."lang" IS 'Language code of the selected language';
|
jbe@532
|
302
|
jbe@532
|
303
|
jbe@532
|
304 CREATE TYPE "authflow" AS ENUM ('code', 'token');
|
jbe@532
|
305
|
jbe@532
|
306 COMMENT ON TYPE "authflow" IS 'OAuth 2.0 flows: ''code'' = Authorization Code flow, ''token'' = Implicit flow';
|
jbe@532
|
307
|
jbe@532
|
308
|
jbe@532
|
309 CREATE TABLE "system_application" (
|
jbe@532
|
310 "id" SERIAL4 PRIMARY KEY,
|
jbe@532
|
311 "name" TEXT NOT NULL,
|
jbe@548
|
312 "discovery_baseurl" TEXT,
|
jbe@532
|
313 "client_id" TEXT NOT NULL UNIQUE,
|
jbe@532
|
314 "default_redirect_uri" TEXT NOT NULL,
|
jbe@532
|
315 "cert_common_name" TEXT,
|
jbe@532
|
316 "client_cred_scope" TEXT,
|
jbe@532
|
317 "flow" "authflow",
|
jbe@532
|
318 "automatic_scope" TEXT,
|
jbe@532
|
319 "permitted_scope" TEXT,
|
jbe@532
|
320 "forbidden_scope" TEXT );
|
jbe@532
|
321
|
jbe@532
|
322 COMMENT ON TABLE "system_application" IS 'OAuth 2.0 clients that are registered by the system administrator';
|
jbe@532
|
323
|
jbe@532
|
324 COMMENT ON COLUMN "system_application"."name" IS 'Human readable name of application';
|
jbe@548
|
325 COMMENT ON COLUMN "system_application"."discovery_baseurl" IS 'Base URL for application discovery; NULL for hidden application';
|
jbe@532
|
326 COMMENT ON COLUMN "system_application"."client_id" IS 'OAuth 2.0 "client_id"';
|
jbe@532
|
327 COMMENT ON COLUMN "system_application"."cert_common_name" IS 'Value for CN field of TLS client certificate';
|
jbe@532
|
328 COMMENT ON COLUMN "system_application"."client_cred_scope" IS 'Space-separated list of scopes; If set, Client Credentials Grant is allowed; value determines scope';
|
jbe@532
|
329 COMMENT ON COLUMN "system_application"."flow" IS 'If set to ''code'' or ''token'', then Authorization Code or Implicit flow is allowed respectively';
|
jbe@532
|
330 COMMENT ON COLUMN "system_application"."automatic_scope" IS 'Space-separated list of scopes; Automatically granted scope for Authorization Code or Implicit flow';
|
jbe@532
|
331 COMMENT ON COLUMN "system_application"."permitted_scope" IS 'Space-separated list of scopes; If set, scope that members may grant to the application is limited to the given value';
|
jbe@532
|
332 COMMENT ON COLUMN "system_application"."forbidden_scope" IS 'Space-separated list of scopes that may not be granted to the application by a member';
|
jbe@532
|
333
|
jbe@532
|
334
|
jbe@532
|
335 CREATE TABLE "system_application_redirect_uri" (
|
jbe@532
|
336 PRIMARY KEY ("system_application_id", "redirect_uri"),
|
jbe@532
|
337 "system_application_id" INT4 REFERENCES "system_application" ("id") ON DELETE CASCADE ON UPDATE CASCADE,
|
jbe@532
|
338 "redirect_uri" TEXT );
|
jbe@532
|
339
|
jbe@532
|
340 COMMENT ON TABLE "system_application_redirect_uri" IS 'Additional OAuth 2.0 redirection endpoints, which may be selected through the "redirect_uri" GET parameter';
|
jbe@532
|
341
|
jbe@532
|
342
|
jbe@532
|
343 CREATE TABLE "dynamic_application_scope" (
|
jbe@532
|
344 PRIMARY KEY ("redirect_uri", "flow", "scope"),
|
jbe@532
|
345 "redirect_uri" TEXT,
|
jbe@532
|
346 "flow" TEXT,
|
jbe@532
|
347 "scope" TEXT,
|
jbe@532
|
348 "expiry" TIMESTAMPTZ NOT NULL DEFAULT now() + '24 hours' );
|
jbe@532
|
349 CREATE INDEX "dynamic_application_scope_redirect_uri_scope_idx" ON "dynamic_application_scope" ("redirect_uri", "flow", "scope");
|
jbe@532
|
350 CREATE INDEX "dynamic_application_scope_expiry_idx" ON "dynamic_application_scope" ("expiry");
|
jbe@532
|
351
|
jbe@532
|
352 COMMENT ON TABLE "dynamic_application_scope" IS 'Dynamic OAuth 2.0 client registration data';
|
jbe@532
|
353
|
jbe@532
|
354 COMMENT ON COLUMN "dynamic_application_scope"."redirect_uri" IS 'Redirection endpoint for which the registration has been done';
|
jbe@532
|
355 COMMENT ON COLUMN "dynamic_application_scope"."flow" IS 'OAuth 2.0 flow for which the registration has been done (see also "system_application"."flow")';
|
jbe@532
|
356 COMMENT ON COLUMN "dynamic_application_scope"."scope" IS 'Single scope without space characters (use multiple rows for more scopes)';
|
jbe@532
|
357 COMMENT ON COLUMN "dynamic_application_scope"."expiry" IS 'Expiry unless renewed';
|
jbe@532
|
358
|
jbe@532
|
359
|
jbe@532
|
360 CREATE TABLE "member_application" (
|
jbe@532
|
361 "id" SERIAL4 PRIMARY KEY,
|
jbe@532
|
362 UNIQUE ("system_application_id", "member_id"),
|
jbe@532
|
363 UNIQUE ("domain", "member_id"),
|
jbe@532
|
364 "member_id" INT4 NOT NULL REFERENCES "member" ("id") ON DELETE CASCADE ON UPDATE CASCADE,
|
jbe@532
|
365 "system_application_id" INT4 REFERENCES "system_application" ("id") ON DELETE CASCADE ON UPDATE CASCADE,
|
jbe@532
|
366 "domain" TEXT,
|
jbe@532
|
367 "session_id" INT8,
|
jbe@532
|
368 FOREIGN KEY ("member_id", "session_id") REFERENCES "session" ("member_id", "id") ON DELETE CASCADE ON UPDATE CASCADE,
|
jbe@532
|
369 "scope" TEXT NOT NULL,
|
jbe@532
|
370 CONSTRAINT "system_application_or_domain_but_not_both" CHECK (
|
jbe@532
|
371 ("system_application_id" NOTNULL AND "domain" ISNULL) OR
|
jbe@532
|
372 ("system_application_id" ISNULL AND "domain" NOTNULL) ) );
|
jbe@532
|
373 CREATE INDEX "member_application_member_id_idx" ON "member_application" ("member_id");
|
jbe@532
|
374
|
jbe@532
|
375 COMMENT ON TABLE "member_application" IS 'Application authorized by a member';
|
jbe@532
|
376
|
jbe@532
|
377 COMMENT ON COLUMN "member_application"."system_application_id" IS 'If set, then application is a system application';
|
jbe@532
|
378 COMMENT ON COLUMN "member_application"."domain" IS 'If set, then application is a dynamically registered OAuth 2.0 client; value is set to client''s domain';
|
jbe@532
|
379 COMMENT ON COLUMN "member_application"."session_id" IS 'If set, registration ends with session';
|
jbe@532
|
380 COMMENT ON COLUMN "member_application"."scope" IS 'Granted scope as space-separated list of strings';
|
jbe@532
|
381
|
jbe@532
|
382
|
jbe@532
|
383 CREATE TYPE "token_type" AS ENUM ('authorization', 'refresh', 'access');
|
jbe@532
|
384
|
jbe@532
|
385 COMMENT ON TYPE "token_type" IS 'Types for entries in "token" table';
|
jbe@532
|
386
|
jbe@532
|
387
|
jbe@532
|
388 CREATE TABLE "token" (
|
jbe@532
|
389 "id" SERIAL8 PRIMARY KEY,
|
jbe@532
|
390 "token" TEXT NOT NULL UNIQUE,
|
jbe@532
|
391 "token_type" "token_type" NOT NULL,
|
jbe@532
|
392 "authorization_token_id" INT8 REFERENCES "token" ("id") ON DELETE CASCADE ON UPDATE CASCADE,
|
jbe@532
|
393 "member_id" INT4 NOT NULL REFERENCES "member" ("id") ON DELETE CASCADE ON UPDATE CASCADE,
|
jbe@532
|
394 "system_application_id" INT4 REFERENCES "system_application" ("id") ON DELETE CASCADE ON UPDATE CASCADE,
|
jbe@532
|
395 "domain" TEXT,
|
jbe@532
|
396 FOREIGN KEY ("member_id", "domain") REFERENCES "member_application" ("member_id", "domain") ON DELETE CASCADE ON UPDATE CASCADE,
|
jbe@532
|
397 "session_id" INT8,
|
jbe@532
|
398 FOREIGN KEY ("member_id", "session_id") REFERENCES "session" ("member_id", "id") ON DELETE RESTRICT ON UPDATE CASCADE, -- NOTE: deletion through "detach_token_from_session" trigger on table "session"
|
jbe@532
|
399 "redirect_uri" TEXT,
|
jbe@532
|
400 "redirect_uri_explicit" BOOLEAN,
|
jbe@532
|
401 "created" TIMESTAMPTZ NOT NULL DEFAULT now(),
|
jbe@532
|
402 "expiry" TIMESTAMPTZ DEFAULT now() + '1 hour',
|
jbe@532
|
403 "used" BOOLEAN NOT NULL DEFAULT FALSE,
|
jbe@532
|
404 "scope" TEXT NOT NULL,
|
jbe@532
|
405 CONSTRAINT "access_token_needs_expiry"
|
jbe@532
|
406 CHECK ("token_type" != 'access'::"token_type" OR "expiry" NOTNULL),
|
jbe@532
|
407 CONSTRAINT "authorization_token_needs_redirect_uri"
|
jbe@532
|
408 CHECK ("token_type" != 'authorization'::"token_type" OR ("redirect_uri" NOTNULL AND "redirect_uri_explicit" NOTNULL) ) );
|
jbe@532
|
409 CREATE INDEX "token_member_id_idx" ON "token" ("member_id");
|
jbe@532
|
410 CREATE INDEX "token_authorization_token_id_idx" ON "token" ("authorization_token_id");
|
jbe@532
|
411 CREATE INDEX "token_expiry_idx" ON "token" ("expiry");
|
jbe@532
|
412
|
jbe@532
|
413 COMMENT ON TABLE "token" IS 'Issued OAuth 2.0 authorization codes and access/refresh tokens';
|
jbe@532
|
414
|
jbe@532
|
415 COMMENT ON COLUMN "token"."token" IS 'String secret (the actual token)';
|
jbe@532
|
416 COMMENT ON COLUMN "token"."authorization_token_id" IS 'Reference to authorization token if tokens were originally created by Authorization Code flow (allows deletion if code is used twice)';
|
jbe@532
|
417 COMMENT ON COLUMN "token"."system_application_id" IS 'If set, then application is a system application';
|
jbe@532
|
418 COMMENT ON COLUMN "token"."domain" IS 'If set, then application is a dynamically registered OAuth 2.0 client; value is set to client''s domain';
|
jbe@532
|
419 COMMENT ON COLUMN "token"."session_id" IS 'If set, then token is tied to a session; Deletion of session sets value to NULL (via trigger) and removes all scopes without suffix ''_detached''';
|
jbe@532
|
420 COMMENT ON COLUMN "token"."redirect_uri" IS 'Authorization codes must be bound to a specific redirect URI';
|
jbe@532
|
421 COMMENT ON COLUMN "token"."redirect_uri_explicit" IS 'True if ''redirect_uri'' parameter was explicitly specified during authorization request of the Authorization Code flow (since RFC 6749 requires it to be included in the access token request in this case)';
|
jbe@532
|
422 COMMENT ON COLUMN "token"."expiry" IS 'Point in time when code or token expired; In case of "used" authorization codes, authorization code must not be deleted as long as tokens exist which refer to the authorization code';
|
jbe@532
|
423 COMMENT ON COLUMN "token"."used" IS 'Can be set to TRUE for authorization codes that have been used (enables deletion of authorization codes that were used twice)';
|
jbe@532
|
424 COMMENT ON COLUMN "token"."scope" IS 'Scope as space-separated list of strings (detached scopes are marked with ''_detached'' suffix)';
|
jbe@532
|
425
|
jbe@532
|
426
|
jbe@532
|
427 CREATE TABLE "token_scope" (
|
jbe@532
|
428 PRIMARY KEY ("token_id", "index"),
|
jbe@532
|
429 "token_id" INT8 REFERENCES "token" ("id") ON DELETE CASCADE ON UPDATE CASCADE,
|
jbe@532
|
430 "index" INT4,
|
jbe@532
|
431 "scope" TEXT NOT NULL );
|
jbe@532
|
432
|
jbe@532
|
433 COMMENT ON TABLE "token_scope" IS 'Additional scopes for an authorization code if ''scope1'', ''scope2'', etc. parameters were used during Authorization Code flow to request several access and refresh tokens at once';
|
jbe@532
|
434
|
jbe@532
|
435
|
jbe@532
|
436 ALTER TABLE "policy" ADD COLUMN "issue_quorum" INT4 CHECK ("issue_quorum" >= 1);
|
jbe@532
|
437 ALTER TABLE "policy" ADD COLUMN "initiative_quorum" INT4 CHECK ("initiative_quorum" >= 1);
|
jbe@532
|
438
|
jbe@532
|
439 UPDATE "policy" SET "issue_quorum" = 1 WHERE "issue_quorum_num" NOTNULL;
|
jbe@532
|
440 UPDATE "policy" SET "initiative_quorum" = 1;
|
jbe@532
|
441
|
jbe@532
|
442 ALTER TABLE "policy" ALTER COLUMN "initiative_quorum" SET NOT NULL;
|
jbe@532
|
443
|
jbe@532
|
444 ALTER TABLE "policy" DROP CONSTRAINT "timing";
|
jbe@532
|
445 ALTER TABLE "policy" DROP CONSTRAINT "issue_quorum_if_and_only_if_not_polling";
|
jbe@532
|
446 ALTER TABLE "policy" ADD CONSTRAINT
|
jbe@532
|
447 "issue_quorum_if_and_only_if_not_polling" CHECK (
|
jbe@532
|
448 "polling" = ("issue_quorum" ISNULL) AND
|
jbe@532
|
449 "polling" = ("issue_quorum_num" ISNULL) AND
|
jbe@532
|
450 "polling" = ("issue_quorum_den" ISNULL)
|
jbe@532
|
451 );
|
jbe@532
|
452 ALTER TABLE "policy" ADD CONSTRAINT
|
jbe@532
|
453 "min_admission_time_smaller_than_max_admission_time" CHECK (
|
jbe@532
|
454 "min_admission_time" < "max_admission_time"
|
jbe@532
|
455 );
|
jbe@532
|
456 ALTER TABLE "policy" ADD CONSTRAINT
|
jbe@532
|
457 "timing_null_or_not_null_constraints" CHECK (
|
jbe@532
|
458 ( "polling" = FALSE AND
|
jbe@532
|
459 "min_admission_time" NOTNULL AND "max_admission_time" NOTNULL AND
|
jbe@532
|
460 "discussion_time" NOTNULL AND
|
jbe@532
|
461 "verification_time" NOTNULL AND
|
jbe@532
|
462 "voting_time" NOTNULL ) OR
|
jbe@532
|
463 ( "polling" = TRUE AND
|
jbe@532
|
464 "min_admission_time" ISNULL AND "max_admission_time" ISNULL AND
|
jbe@532
|
465 "discussion_time" NOTNULL AND
|
jbe@532
|
466 "verification_time" NOTNULL AND
|
jbe@532
|
467 "voting_time" NOTNULL ) OR
|
jbe@532
|
468 ( "polling" = TRUE AND
|
jbe@532
|
469 "min_admission_time" ISNULL AND "max_admission_time" ISNULL AND
|
jbe@532
|
470 "discussion_time" ISNULL AND
|
jbe@532
|
471 "verification_time" ISNULL AND
|
jbe@532
|
472 "voting_time" ISNULL )
|
jbe@532
|
473 );
|
jbe@532
|
474
|
jbe@532
|
475 COMMENT ON COLUMN "policy"."min_admission_time" IS 'Minimum duration of issue state ''admission''; Minimum time an issue stays open; Note: should be considerably smaller than "max_admission_time"';
|
jbe@532
|
476 COMMENT ON COLUMN "policy"."issue_quorum" IS 'Absolute number of supporters needed by an initiative to be "accepted", i.e. pass from ''admission'' to ''discussion'' state';
|
jbe@532
|
477 COMMENT ON COLUMN "policy"."issue_quorum_num" IS 'Numerator of supporter quorum to be reached by an initiative to be "accepted", i.e. pass from ''admission'' to ''discussion'' state (Note: further requirements apply, see quorum columns of "area" table)';
|
jbe@532
|
478 COMMENT ON COLUMN "policy"."issue_quorum_den" IS 'Denominator of supporter quorum to be reached by an initiative to be "accepted", i.e. pass from ''admission'' to ''discussion'' state (Note: further requirements apply, see quorum columns of "area" table)';
|
jbe@532
|
479 COMMENT ON COLUMN "policy"."initiative_quorum" IS 'Absolute number of satisfied supporters to be reached by an initiative to be "admitted" for voting';
|
jbe@532
|
480 COMMENT ON COLUMN "policy"."initiative_quorum_num" IS 'Numerator of satisfied supporter quorum to be reached by an initiative to be "admitted" for voting';
|
jbe@532
|
481 COMMENT ON COLUMN "policy"."initiative_quorum_den" IS 'Denominator of satisfied supporter quorum to be reached by an initiative to be "admitted" for voting';
|
jbe@532
|
482
|
jbe@532
|
483
|
jbe@551
|
484 ALTER TABLE "unit" ADD COLUMN "location" JSONB;
|
jbe@551
|
485
|
jbe@551
|
486 CREATE INDEX "unit_location_idx" ON "unit" USING gist ((GeoJSON_to_ecluster("location")));
|
jbe@532
|
487
|
jbe@556
|
488 COMMENT ON COLUMN "unit"."member_count" IS 'Count of members as determined by column "voting_right" in table "privilege" (only active members counted)';
|
jbe@551
|
489 COMMENT ON COLUMN "unit"."location" IS 'Geographic location on earth as GeoJSON object indicating valid coordinates for initiatives of issues with this policy';
|
jbe@532
|
490
|
jbe@532
|
491
|
jbe@532
|
492 DROP INDEX "area_unit_id_idx";
|
jbe@532
|
493 ALTER TABLE "area" ADD UNIQUE ("unit_id", "id");
|
jbe@532
|
494
|
jbe@532
|
495 ALTER TABLE "area" ADD COLUMN "quorum_standard" NUMERIC NOT NULL DEFAULT 2 CHECK ("quorum_standard" >= 0);
|
jbe@532
|
496 ALTER TABLE "area" ADD COLUMN "quorum_issues" NUMERIC NOT NULL DEFAULT 1 CHECK ("quorum_issues" > 0);
|
jbe@532
|
497 ALTER TABLE "area" ADD COLUMN "quorum_time" INTERVAL NOT NULL DEFAULT '1 day' CHECK ("quorum_time" > '0'::INTERVAL);
|
jbe@532
|
498 ALTER TABLE "area" ADD COLUMN "quorum_exponent" NUMERIC NOT NULL DEFAULT 0.5 CHECK ("quorum_exponent" BETWEEN 0 AND 1);
|
jbe@532
|
499 ALTER TABLE "area" ADD COLUMN "quorum_factor" NUMERIC NOT NULL DEFAULT 2 CHECK ("quorum_factor" >= 1);
|
jbe@532
|
500 ALTER TABLE "area" ADD COLUMN "quorum_den" INT4 CHECK ("quorum_den" > 0);
|
jbe@532
|
501 ALTER TABLE "area" ADD COLUMN "issue_quorum" INT4;
|
jbe@551
|
502 ALTER TABLE "area" ADD COLUMN "location" JSONB;
|
jbe@532
|
503
|
jbe@532
|
504 ALTER TABLE "area" DROP COLUMN "direct_member_count";
|
jbe@532
|
505 ALTER TABLE "area" DROP COLUMN "member_weight";
|
jbe@532
|
506
|
jbe@551
|
507 CREATE INDEX "area_location_idx" ON "area" USING gist ((GeoJSON_to_ecluster("location")));
|
jbe@532
|
508
|
jbe@532
|
509 COMMENT ON COLUMN "area"."quorum_standard" IS 'Parameter for dynamic issue quorum: default quorum';
|
jbe@532
|
510 COMMENT ON COLUMN "area"."quorum_issues" IS 'Parameter for dynamic issue quorum: number of open issues for default quorum';
|
jbe@532
|
511 COMMENT ON COLUMN "area"."quorum_time" IS 'Parameter for dynamic issue quorum: discussion, verification, and voting time of open issues to result in the given default quorum (open issues with shorter time will increase quorum and open issues with longer time will reduce quorum if "quorum_exponent" is greater than zero)';
|
jbe@532
|
512 COMMENT ON COLUMN "area"."quorum_exponent" IS 'Parameter for dynamic issue quorum: set to zero to ignore duration of open issues, set to one to fully take duration of open issues into account; defaults to 0.5';
|
jbe@532
|
513 COMMENT ON COLUMN "area"."quorum_factor" IS 'Parameter for dynamic issue quorum: factor to increase dynamic quorum when a number of "quorum_issues" issues with "quorum_time" duration of discussion, verification, and voting phase are added to the number of open admitted issues';
|
jbe@532
|
514 COMMENT ON COLUMN "area"."quorum_den" IS 'Parameter for dynamic issue quorum: when set, dynamic quorum is multiplied with "issue"."population" and divided by "quorum_den" (and then rounded up)';
|
jbe@532
|
515 COMMENT ON COLUMN "area"."issue_quorum" IS 'Additional dynamic issue quorum based on the number of open accepted issues; automatically calculated by function "issue_admission"';
|
jbe@532
|
516 COMMENT ON COLUMN "area"."external_reference" IS 'Opaque data field to store an external reference';
|
jbe@551
|
517 COMMENT ON COLUMN "area"."location" IS 'Geographic location on earth as GeoJSON object indicating valid coordinates for initiatives of issues with this policy';
|
jbe@532
|
518
|
jbe@532
|
519
|
jbe@532
|
520 CREATE TABLE "snapshot" (
|
jbe@532
|
521 UNIQUE ("issue_id", "id"), -- index needed for foreign-key on table "issue"
|
jbe@532
|
522 "id" SERIAL8 PRIMARY KEY,
|
jbe@532
|
523 "calculated" TIMESTAMPTZ NOT NULL DEFAULT now(),
|
jbe@532
|
524 "population" INT4,
|
jbe@532
|
525 "area_id" INT4 NOT NULL REFERENCES "area" ("id") ON DELETE CASCADE ON UPDATE CASCADE,
|
jbe@532
|
526 "issue_id" INT4 ); -- NOTE: following (cyclic) reference is added later through ALTER command: REFERENCES "issue" ("id") ON DELETE CASCADE ON UPDATE CASCADE
|
jbe@532
|
527
|
jbe@532
|
528 COMMENT ON TABLE "snapshot" IS 'Point in time when a snapshot of one or more issues (see table "snapshot_issue") and their supporter situation is taken';
|
jbe@532
|
529
|
jbe@532
|
530
|
jbe@532
|
531 CREATE TABLE "snapshot_population" (
|
jbe@532
|
532 PRIMARY KEY ("snapshot_id", "member_id"),
|
jbe@532
|
533 "snapshot_id" INT8 REFERENCES "snapshot" ("id") ON DELETE CASCADE ON UPDATE CASCADE,
|
jbe@532
|
534 "member_id" INT4 REFERENCES "member" ("id") ON DELETE RESTRICT ON UPDATE CASCADE );
|
jbe@532
|
535
|
jbe@532
|
536 COMMENT ON TABLE "snapshot_population" IS 'Members with voting right relevant for a snapshot';
|
jbe@532
|
537
|
jbe@532
|
538
|
jbe@532
|
539 ALTER TABLE "issue" ADD UNIQUE ("area_id", "id");
|
jbe@532
|
540 DROP INDEX "issue_area_id_idx";
|
jbe@536
|
541 ALTER TABLE "issue" ADD UNIQUE ("policy_id", "id");
|
jbe@536
|
542 DROP INDEX "issue_policy_id_idx";
|
jbe@532
|
543
|
jbe@532
|
544 ALTER TABLE "issue" RENAME COLUMN "snapshot" TO "calculated";
|
jbe@532
|
545
|
jbe@532
|
546 ALTER TABLE "issue" ADD COLUMN "latest_snapshot_id" INT8 REFERENCES "snapshot" ("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
jbe@532
|
547 ALTER TABLE "issue" ADD COLUMN "admission_snapshot_id" INT8 REFERENCES "snapshot" ("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
jbe@532
|
548 ALTER TABLE "issue" ADD COLUMN "half_freeze_snapshot_id" INT8;
|
jbe@532
|
549 ALTER TABLE "issue" ADD COLUMN "full_freeze_snapshot_id" INT8;
|
jbe@532
|
550
|
jbe@532
|
551 ALTER TABLE "issue" ADD FOREIGN KEY ("id", "half_freeze_snapshot_id")
|
jbe@532
|
552 REFERENCES "snapshot" ("issue_id", "id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
jbe@532
|
553 ALTER TABLE "issue" ADD FOREIGN KEY ("id", "full_freeze_snapshot_id")
|
jbe@532
|
554 REFERENCES "snapshot" ("issue_id", "id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
jbe@532
|
555
|
jbe@532
|
556 ALTER TABLE "issue" DROP CONSTRAINT "last_snapshot_on_full_freeze";
|
jbe@532
|
557 ALTER TABLE "issue" DROP CONSTRAINT "freeze_requires_snapshot";
|
jbe@532
|
558 ALTER TABLE "issue" DROP CONSTRAINT "set_both_or_none_of_snapshot_and_latest_snapshot_event";
|
jbe@532
|
559
|
jbe@532
|
560 CREATE INDEX "issue_state_idx" ON "issue" ("state");
|
jbe@532
|
561 CREATE INDEX "issue_latest_snapshot_id" ON "issue" ("latest_snapshot_id");
|
jbe@532
|
562 CREATE INDEX "issue_admission_snapshot_id" ON "issue" ("admission_snapshot_id");
|
jbe@532
|
563 CREATE INDEX "issue_half_freeze_snapshot_id" ON "issue" ("half_freeze_snapshot_id");
|
jbe@532
|
564 CREATE INDEX "issue_full_freeze_snapshot_id" ON "issue" ("full_freeze_snapshot_id");
|
jbe@532
|
565
|
jbe@532
|
566 COMMENT ON COLUMN "issue"."accepted" IS 'Point in time, when the issue was accepted for further discussion (see columns "issue_quorum_num" and "issue_quorum_den" of table "policy" and quorum columns of table "area")';
|
jbe@532
|
567 COMMENT ON COLUMN "issue"."calculated" IS 'Point in time, when most recent snapshot and "population" and *_count values were calculated (NOTE: value is equal to "snapshot"."calculated" of snapshot with "id"="issue"."latest_snapshot_id")';
|
jbe@532
|
568 COMMENT ON COLUMN "issue"."latest_snapshot_id" IS 'Snapshot id of most recent snapshot';
|
jbe@532
|
569 COMMENT ON COLUMN "issue"."admission_snapshot_id" IS 'Snapshot id when issue as accepted or canceled in admission phase';
|
jbe@532
|
570 COMMENT ON COLUMN "issue"."half_freeze_snapshot_id" IS 'Snapshot id at end of discussion phase';
|
jbe@532
|
571 COMMENT ON COLUMN "issue"."full_freeze_snapshot_id" IS 'Snapshot id at end of verification phase';
|
jbe@532
|
572 COMMENT ON COLUMN "issue"."population" IS 'Count of members in "snapshot_population" table with "snapshot_id" equal to "issue"."latest_snapshot_id"';
|
jbe@532
|
573
|
jbe@532
|
574
|
jbe@532
|
575 ALTER TABLE "snapshot" ADD FOREIGN KEY ("issue_id") REFERENCES "issue" ("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
jbe@532
|
576
|
jbe@532
|
577
|
jbe@532
|
578 ALTER TABLE "initiative" DROP CONSTRAINT "initiative_suggested_initiative_id_fkey";
|
jbe@532
|
579 ALTER TABLE "initiative" ADD FOREIGN KEY ("suggested_initiative_id") REFERENCES "initiative" ("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
jbe@532
|
580
|
jbe@532
|
581 ALTER TABLE "initiative" ADD COLUMN "location" JSONB;
|
jbe@532
|
582 ALTER TABLE "initiative" ADD COLUMN "draft_text_search_data" TSVECTOR;
|
jbe@532
|
583
|
jbe@532
|
584 CREATE INDEX "initiative_location_idx" ON "initiative" USING gist ((GeoJSON_to_ecluster("location")));
|
jbe@532
|
585 CREATE INDEX "initiative_draft_text_search_data_idx" ON "initiative" USING gin ("draft_text_search_data");
|
jbe@532
|
586
|
jbe@532
|
587 COMMENT ON COLUMN "initiative"."location" IS 'Geographic location of initiative as GeoJSON object (automatically copied from most recent draft)';
|
jbe@532
|
588
|
jbe@532
|
589
|
jbe@532
|
590 ALTER TABLE "draft" ADD COLUMN "location" JSONB;
|
jbe@532
|
591
|
jbe@532
|
592 CREATE INDEX "draft_location_idx" ON "draft" USING gist ((GeoJSON_to_ecluster("location")));
|
jbe@532
|
593
|
jbe@532
|
594 COMMENT ON COLUMN "draft"."location" IS 'Geographic location of initiative as GeoJSON object (automatically copied to "initiative" table if draft is most recent)';
|
jbe@532
|
595
|
jbe@532
|
596
|
jbe@532
|
597 ALTER TABLE "suggestion" ADD COLUMN "location" JSONB;
|
jbe@532
|
598
|
jbe@532
|
599 CREATE INDEX "suggestion_location_idx" ON "suggestion" USING gist ((GeoJSON_to_ecluster("location")));
|
jbe@532
|
600
|
jbe@532
|
601 COMMENT ON COLUMN "suggestion"."location" IS 'Geographic location of suggestion as GeoJSON object';
|
jbe@532
|
602
|
jbe@532
|
603
|
jbe@532
|
604 CREATE TABLE "temporary_suggestion_counts" (
|
jbe@532
|
605 "id" INT8 PRIMARY KEY, -- NOTE: no referential integrity due to performance/locking issues; REFERENCES "suggestion" ("id") ON DELETE CASCADE ON UPDATE CASCADE,
|
jbe@532
|
606 "minus2_unfulfilled_count" INT4 NOT NULL,
|
jbe@532
|
607 "minus2_fulfilled_count" INT4 NOT NULL,
|
jbe@532
|
608 "minus1_unfulfilled_count" INT4 NOT NULL,
|
jbe@532
|
609 "minus1_fulfilled_count" INT4 NOT NULL,
|
jbe@532
|
610 "plus1_unfulfilled_count" INT4 NOT NULL,
|
jbe@532
|
611 "plus1_fulfilled_count" INT4 NOT NULL,
|
jbe@532
|
612 "plus2_unfulfilled_count" INT4 NOT NULL,
|
jbe@532
|
613 "plus2_fulfilled_count" INT4 NOT NULL );
|
jbe@532
|
614
|
jbe@532
|
615 COMMENT ON TABLE "temporary_suggestion_counts" IS 'Holds certain calculated values (suggestion counts) temporarily until they can be copied into table "suggestion"';
|
jbe@532
|
616
|
jbe@532
|
617 COMMENT ON COLUMN "temporary_suggestion_counts"."id" IS 'References "suggestion" ("id") but has no referential integrity trigger associated, due to performance/locking issues';
|
jbe@532
|
618
|
jbe@532
|
619
|
jbe@532
|
620 ALTER TABLE "interest" DROP CONSTRAINT "interest_member_id_fkey";
|
jbe@532
|
621 ALTER TABLE "interest" ADD FOREIGN KEY ("member_id") REFERENCES "member" ("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
jbe@532
|
622
|
jbe@532
|
623
|
jbe@532
|
624 ALTER TABLE "initiator" DROP CONSTRAINT "initiator_member_id_fkey";
|
jbe@532
|
625 ALTER TABLE "initiator" ADD FOREIGN KEY ("member_id") REFERENCES "member" ("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
jbe@532
|
626
|
jbe@532
|
627
|
jbe@532
|
628 ALTER TABLE "delegation" DROP CONSTRAINT "delegation_trustee_id_fkey";
|
jbe@532
|
629 ALTER TABLE "delegation" ADD FOREIGN KEY ("trustee_id") REFERENCES "member" ("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
jbe@532
|
630
|
jbe@532
|
631
|
jbe@532
|
632 CREATE TABLE "snapshot_issue" (
|
jbe@532
|
633 PRIMARY KEY ("snapshot_id", "issue_id"),
|
jbe@532
|
634 "snapshot_id" INT8 REFERENCES "snapshot" ("id") ON DELETE CASCADE ON UPDATE CASCADE,
|
jbe@532
|
635 "issue_id" INT4 REFERENCES "issue" ("id") ON DELETE CASCADE ON UPDATE CASCADE );
|
jbe@532
|
636 CREATE INDEX "snapshot_issue_issue_id_idx" ON "snapshot_issue" ("issue_id");
|
jbe@532
|
637
|
jbe@532
|
638 COMMENT ON TABLE "snapshot_issue" IS 'List of issues included in a snapshot';
|
jbe@532
|
639
|
jbe@532
|
640 COMMENT ON COLUMN "snapshot_issue"."issue_id" IS 'Issue being part of the snapshot; Trigger "delete_snapshot_on_partial_delete" on "snapshot_issue" table will delete snapshot if an issue of the snapshot is deleted.';
|
jbe@532
|
641
|
jbe@532
|
642
|
jbe@532
|
643 ALTER TABLE "direct_interest_snapshot" RENAME TO "direct_interest_snapshot_old"; -- TODO!
|
jbe@532
|
644 ALTER INDEX "direct_interest_snapshot_pkey" RENAME TO "direct_interest_snapshot_old_pkey";
|
jbe@532
|
645 ALTER INDEX "direct_interest_snapshot_member_id_idx" RENAME TO "direct_interest_snapshot_old_member_id_idx";
|
jbe@532
|
646
|
jbe@532
|
647 ALTER TABLE "delegating_interest_snapshot" RENAME TO "delegating_interest_snapshot_old"; -- TODO!
|
jbe@532
|
648 ALTER INDEX "delegating_interest_snapshot_pkey" RENAME TO "delegating_interest_snapshot_old_pkey";
|
jbe@532
|
649 ALTER INDEX "delegating_interest_snapshot_member_id_idx" RENAME TO "delegating_interest_snapshot_old_member_id_idx";
|
jbe@532
|
650
|
jbe@532
|
651 ALTER TABLE "direct_supporter_snapshot" RENAME TO "direct_supporter_snapshot_old"; -- TODO!
|
jbe@532
|
652 ALTER INDEX "direct_supporter_snapshot_pkey" RENAME TO "direct_supporter_snapshot_old_pkey";
|
jbe@532
|
653 ALTER INDEX "direct_supporter_snapshot_member_id_idx" RENAME TO "direct_supporter_snapshot_old_member_id_idx";
|
jbe@532
|
654
|
jbe@532
|
655
|
jbe@532
|
656 CREATE TABLE "direct_interest_snapshot" (
|
jbe@532
|
657 PRIMARY KEY ("snapshot_id", "issue_id", "member_id"),
|
jbe@532
|
658 "snapshot_id" INT8,
|
jbe@532
|
659 "issue_id" INT4,
|
jbe@532
|
660 FOREIGN KEY ("snapshot_id", "issue_id")
|
jbe@532
|
661 REFERENCES "snapshot_issue" ("snapshot_id", "issue_id") ON DELETE CASCADE ON UPDATE CASCADE,
|
jbe@532
|
662 "member_id" INT4 REFERENCES "member" ("id") ON DELETE RESTRICT ON UPDATE RESTRICT,
|
jbe@532
|
663 "weight" INT4 );
|
jbe@532
|
664 CREATE INDEX "direct_interest_snapshot_member_id_idx" ON "direct_interest_snapshot" ("member_id");
|
jbe@532
|
665
|
jbe@532
|
666 COMMENT ON TABLE "direct_interest_snapshot" IS 'Snapshot of active members having an "interest" in the "issue"; for corrections refer to column "issue_notice" of "issue" table';
|
jbe@532
|
667
|
jbe@532
|
668 COMMENT ON COLUMN "direct_interest_snapshot"."weight" IS 'Weight of member (1 or higher) according to "delegating_interest_snapshot"';
|
jbe@532
|
669
|
jbe@532
|
670
|
jbe@532
|
671 CREATE TABLE "delegating_interest_snapshot" (
|
jbe@532
|
672 PRIMARY KEY ("snapshot_id", "issue_id", "member_id"),
|
jbe@532
|
673 "snapshot_id" INT8,
|
jbe@532
|
674 "issue_id" INT4,
|
jbe@532
|
675 FOREIGN KEY ("snapshot_id", "issue_id")
|
jbe@532
|
676 REFERENCES "snapshot_issue" ("snapshot_id", "issue_id") ON DELETE CASCADE ON UPDATE CASCADE,
|
jbe@532
|
677 "member_id" INT4 REFERENCES "member" ("id") ON DELETE RESTRICT ON UPDATE RESTRICT,
|
jbe@532
|
678 "weight" INT4,
|
jbe@532
|
679 "scope" "delegation_scope" NOT NULL,
|
jbe@532
|
680 "delegate_member_ids" INT4[] NOT NULL );
|
jbe@532
|
681 CREATE INDEX "delegating_interest_snapshot_member_id_idx" ON "delegating_interest_snapshot" ("member_id");
|
jbe@532
|
682
|
jbe@532
|
683 COMMENT ON TABLE "delegating_interest_snapshot" IS 'Delegations increasing the weight of entries in the "direct_interest_snapshot" table; for corrections refer to column "issue_notice" of "issue" table';
|
jbe@532
|
684
|
jbe@532
|
685 COMMENT ON COLUMN "delegating_interest_snapshot"."member_id" IS 'Delegating member';
|
jbe@532
|
686 COMMENT ON COLUMN "delegating_interest_snapshot"."weight" IS 'Intermediate weight';
|
jbe@532
|
687 COMMENT ON COLUMN "delegating_interest_snapshot"."delegate_member_ids" IS 'Chain of members who act as delegates; last entry referes to "member_id" column of table "direct_interest_snapshot"';
|
jbe@532
|
688
|
jbe@532
|
689
|
jbe@532
|
690 CREATE TABLE "direct_supporter_snapshot" (
|
jbe@532
|
691 PRIMARY KEY ("snapshot_id", "initiative_id", "member_id"),
|
jbe@532
|
692 "snapshot_id" INT8,
|
jbe@532
|
693 "issue_id" INT4 NOT NULL,
|
jbe@532
|
694 FOREIGN KEY ("snapshot_id", "issue_id")
|
jbe@532
|
695 REFERENCES "snapshot_issue" ("snapshot_id", "issue_id") ON DELETE CASCADE ON UPDATE CASCADE,
|
jbe@532
|
696 "initiative_id" INT4,
|
jbe@532
|
697 "member_id" INT4 REFERENCES "member" ("id") ON DELETE RESTRICT ON UPDATE RESTRICT,
|
jbe@532
|
698 "draft_id" INT8 NOT NULL,
|
jbe@532
|
699 "informed" BOOLEAN NOT NULL,
|
jbe@532
|
700 "satisfied" BOOLEAN NOT NULL,
|
jbe@532
|
701 FOREIGN KEY ("issue_id", "initiative_id") REFERENCES "initiative" ("issue_id", "id") ON DELETE CASCADE ON UPDATE CASCADE,
|
jbe@532
|
702 FOREIGN KEY ("initiative_id", "draft_id") REFERENCES "draft" ("initiative_id", "id") ON DELETE NO ACTION ON UPDATE CASCADE,
|
jbe@532
|
703 FOREIGN KEY ("snapshot_id", "issue_id", "member_id") REFERENCES "direct_interest_snapshot" ("snapshot_id", "issue_id", "member_id") ON DELETE CASCADE ON UPDATE CASCADE );
|
jbe@532
|
704 CREATE INDEX "direct_supporter_snapshot_member_id_idx" ON "direct_supporter_snapshot" ("member_id");
|
jbe@532
|
705
|
jbe@532
|
706 COMMENT ON TABLE "direct_supporter_snapshot" IS 'Snapshot of supporters of initiatives (weight is stored in "direct_interest_snapshot"); for corrections refer to column "issue_notice" of "issue" table';
|
jbe@532
|
707
|
jbe@532
|
708 COMMENT ON COLUMN "direct_supporter_snapshot"."issue_id" IS 'WARNING: No index: For selections use column "initiative_id" and join via table "initiative" where neccessary';
|
jbe@532
|
709 COMMENT ON COLUMN "direct_supporter_snapshot"."informed" IS 'Supporter has seen the latest draft of the initiative';
|
jbe@532
|
710 COMMENT ON COLUMN "direct_supporter_snapshot"."satisfied" IS 'Supporter has no "critical_opinion"s';
|
jbe@532
|
711
|
jbe@532
|
712
|
jbe@532
|
713 ALTER TABLE "non_voter" DROP CONSTRAINT "non_voter_pkey";
|
jbe@532
|
714 DROP INDEX "non_voter_member_id_idx";
|
jbe@532
|
715
|
jbe@532
|
716 ALTER TABLE "non_voter" ADD PRIMARY KEY ("member_id", "issue_id");
|
jbe@532
|
717 CREATE INDEX "non_voter_issue_id_idx" ON "non_voter" ("issue_id");
|
jbe@532
|
718
|
jbe@532
|
719
|
jbe@545
|
720 INSERT INTO "member_useterms" ("member_id", "accepted", "contract_identifier")
|
jbe@545
|
721 SELECT
|
jbe@545
|
722 "member_id",
|
jbe@545
|
723 regexp_replace("value", '^accepted at ', '')::TIMESTAMPTZ AS "accepted",
|
jbe@545
|
724 regexp_replace("key", '^use_terms_checkbox_', '') AS "contract_identifier"
|
jbe@545
|
725 FROM "setting" WHERE "key" LIKE 'use_terms_checkbox_%';
|
jbe@545
|
726
|
jbe@545
|
727
|
jbe@542
|
728 DROP TABLE "setting";
|
jbe@542
|
729 DROP TABLE "setting_map";
|
jbe@542
|
730 DROP TABLE "member_relation_setting";
|
jbe@542
|
731 DROP TABLE "unit_setting";
|
jbe@542
|
732 DROP TABLE "area_setting";
|
jbe@542
|
733 DROP TABLE "initiative_setting";
|
jbe@542
|
734 DROP TABLE "suggestion_setting";
|
jbe@542
|
735
|
jbe@542
|
736
|
jbe@532
|
737 ALTER TABLE "event" ADD COLUMN "other_member_id" INT4 REFERENCES "member" ("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
jbe@532
|
738 ALTER TABLE "event" ADD COLUMN "scope" "delegation_scope";
|
jbe@532
|
739 ALTER TABLE "event" ADD COLUMN "unit_id" INT4 REFERENCES "unit" ("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
jbe@532
|
740 ALTER TABLE "event" ADD COLUMN "area_id" INT4;
|
jbe@536
|
741 ALTER TABLE "event" ADD COLUMN "policy_id" INT4 REFERENCES "policy" ("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
jbe@532
|
742 ALTER TABLE "event" ADD COLUMN "boolean_value" BOOLEAN;
|
jbe@532
|
743 ALTER TABLE "event" ADD COLUMN "numeric_value" INT4;
|
jbe@532
|
744 ALTER TABLE "event" ADD COLUMN "text_value" TEXT;
|
jbe@532
|
745 ALTER TABLE "event" ADD COLUMN "old_text_value" TEXT;
|
jbe@532
|
746
|
jbe@532
|
747 ALTER TABLE "event" ADD FOREIGN KEY ("unit_id", "area_id") REFERENCES "area" ("unit_id", "id") ON DELETE CASCADE ON UPDATE CASCADE;
|
jbe@532
|
748 ALTER TABLE "event" ADD FOREIGN KEY ("area_id", "issue_id") REFERENCES "issue" ("area_id", "id") ON DELETE CASCADE ON UPDATE CASCADE;
|
jbe@536
|
749 ALTER TABLE "event" ADD FOREIGN KEY ("policy_id", "issue_id") REFERENCES "issue" ("policy_id", "id") ON DELETE CASCADE ON UPDATE CASCADE;
|
jbe@532
|
750
|
jbe@532
|
751 ALTER TABLE "event" DROP CONSTRAINT "event_initiative_id_fkey1";
|
jbe@532
|
752 ALTER TABLE "event" DROP CONSTRAINT "null_constr_for_issue_state_changed";
|
jbe@532
|
753 ALTER TABLE "event" DROP CONSTRAINT "null_constr_for_initiative_creation_or_revocation_or_new_draft";
|
jbe@532
|
754 ALTER TABLE "event" DROP CONSTRAINT "null_constr_for_suggestion_creation";
|
jbe@532
|
755
|
jbe@553
|
756 UPDATE "event" SET
|
jbe@553
|
757 "unit_id" = "area"."unit_id",
|
jbe@553
|
758 "area_id" = "issue"."area_id",
|
jbe@553
|
759 "policy_id" = "issue"."policy_id"
|
jbe@532
|
760 FROM "issue", "area"
|
jbe@532
|
761 WHERE "issue"."id" = "event"."issue_id" AND "area"."id" = "issue"."area_id";
|
jbe@532
|
762
|
jbe@532
|
763 ALTER TABLE "event" ADD CONSTRAINT "constr_for_issue_state_changed" CHECK (
|
jbe@532
|
764 "event" != 'issue_state_changed' OR (
|
jbe@532
|
765 "member_id" ISNULL AND
|
jbe@532
|
766 "other_member_id" ISNULL AND
|
jbe@532
|
767 "scope" ISNULL AND
|
jbe@532
|
768 "unit_id" NOTNULL AND
|
jbe@532
|
769 "area_id" NOTNULL AND
|
jbe@536
|
770 "policy_id" NOTNULL AND
|
jbe@532
|
771 "issue_id" NOTNULL AND
|
jbe@532
|
772 "state" NOTNULL AND
|
jbe@532
|
773 "initiative_id" ISNULL AND
|
jbe@532
|
774 "draft_id" ISNULL AND
|
jbe@532
|
775 "suggestion_id" ISNULL AND
|
jbe@532
|
776 "boolean_value" ISNULL AND
|
jbe@532
|
777 "numeric_value" ISNULL AND
|
jbe@532
|
778 "text_value" ISNULL AND
|
jbe@532
|
779 "old_text_value" ISNULL ));
|
jbe@532
|
780 ALTER TABLE "event" ADD CONSTRAINT "constr_for_initiative_creation_or_revocation_or_new_draft" CHECK (
|
jbe@532
|
781 "event" NOT IN (
|
jbe@532
|
782 'initiative_created_in_new_issue',
|
jbe@532
|
783 'initiative_created_in_existing_issue',
|
jbe@532
|
784 'initiative_revoked',
|
jbe@532
|
785 'new_draft_created'
|
jbe@532
|
786 ) OR (
|
jbe@532
|
787 "member_id" NOTNULL AND
|
jbe@532
|
788 "other_member_id" ISNULL AND
|
jbe@532
|
789 "scope" ISNULL AND
|
jbe@532
|
790 "unit_id" NOTNULL AND
|
jbe@532
|
791 "area_id" NOTNULL AND
|
jbe@536
|
792 "policy_id" NOTNULL AND
|
jbe@532
|
793 "issue_id" NOTNULL AND
|
jbe@532
|
794 "state" NOTNULL AND
|
jbe@532
|
795 "initiative_id" NOTNULL AND
|
jbe@532
|
796 "draft_id" NOTNULL AND
|
jbe@532
|
797 "suggestion_id" ISNULL AND
|
jbe@532
|
798 "boolean_value" ISNULL AND
|
jbe@532
|
799 "numeric_value" ISNULL AND
|
jbe@532
|
800 "text_value" ISNULL AND
|
jbe@532
|
801 "old_text_value" ISNULL ));
|
jbe@532
|
802 ALTER TABLE "event" ADD CONSTRAINT "constr_for_suggestion_creation" CHECK (
|
jbe@532
|
803 "event" != 'suggestion_created' OR (
|
jbe@532
|
804 "member_id" NOTNULL AND
|
jbe@532
|
805 "other_member_id" ISNULL AND
|
jbe@532
|
806 "scope" ISNULL AND
|
jbe@532
|
807 "unit_id" NOTNULL AND
|
jbe@532
|
808 "area_id" NOTNULL AND
|
jbe@536
|
809 "policy_id" NOTNULL AND
|
jbe@532
|
810 "issue_id" NOTNULL AND
|
jbe@532
|
811 "state" NOTNULL AND
|
jbe@532
|
812 "initiative_id" NOTNULL AND
|
jbe@532
|
813 "draft_id" ISNULL AND
|
jbe@532
|
814 "suggestion_id" NOTNULL AND
|
jbe@532
|
815 "boolean_value" ISNULL AND
|
jbe@532
|
816 "numeric_value" ISNULL AND
|
jbe@532
|
817 "text_value" ISNULL AND
|
jbe@532
|
818 "old_text_value" ISNULL ));
|
jbe@532
|
819 ALTER TABLE "event" ADD CONSTRAINT "constr_for_suggestion_removal" CHECK (
|
jbe@554
|
820 "event" != 'suggestion_deleted' OR (
|
jbe@532
|
821 "member_id" ISNULL AND
|
jbe@532
|
822 "other_member_id" ISNULL AND
|
jbe@532
|
823 "scope" ISNULL AND
|
jbe@532
|
824 "unit_id" NOTNULL AND
|
jbe@532
|
825 "area_id" NOTNULL AND
|
jbe@536
|
826 "policy_id" NOTNULL AND
|
jbe@532
|
827 "issue_id" NOTNULL AND
|
jbe@532
|
828 "state" NOTNULL AND
|
jbe@532
|
829 "initiative_id" NOTNULL AND
|
jbe@532
|
830 "draft_id" ISNULL AND
|
jbe@532
|
831 "suggestion_id" NOTNULL AND
|
jbe@532
|
832 "boolean_value" ISNULL AND
|
jbe@532
|
833 "numeric_value" ISNULL AND
|
jbe@532
|
834 "text_value" ISNULL AND
|
jbe@532
|
835 "old_text_value" ISNULL ));
|
jbe@532
|
836 ALTER TABLE "event" ADD CONSTRAINT "constr_for_value_less_member_event" CHECK (
|
jbe@532
|
837 "event" NOT IN (
|
jbe@532
|
838 'member_activated',
|
jbe@554
|
839 'member_deleted',
|
jbe@532
|
840 'member_profile_updated',
|
jbe@532
|
841 'member_image_updated'
|
jbe@532
|
842 ) OR (
|
jbe@532
|
843 "member_id" NOTNULL AND
|
jbe@532
|
844 "other_member_id" ISNULL AND
|
jbe@532
|
845 "scope" ISNULL AND
|
jbe@532
|
846 "unit_id" ISNULL AND
|
jbe@532
|
847 "area_id" ISNULL AND
|
jbe@536
|
848 "policy_id" ISNULL AND
|
jbe@532
|
849 "issue_id" ISNULL AND
|
jbe@532
|
850 "state" ISNULL AND
|
jbe@532
|
851 "initiative_id" ISNULL AND
|
jbe@532
|
852 "draft_id" ISNULL AND
|
jbe@532
|
853 "suggestion_id" ISNULL AND
|
jbe@532
|
854 "boolean_value" ISNULL AND
|
jbe@532
|
855 "numeric_value" ISNULL AND
|
jbe@532
|
856 "text_value" ISNULL AND
|
jbe@532
|
857 "old_text_value" ISNULL ));
|
jbe@532
|
858 ALTER TABLE "event" ADD CONSTRAINT "constr_for_member_active" CHECK (
|
jbe@532
|
859 "event" != 'member_active' OR (
|
jbe@532
|
860 "member_id" NOTNULL AND
|
jbe@532
|
861 "other_member_id" ISNULL AND
|
jbe@532
|
862 "scope" ISNULL AND
|
jbe@532
|
863 "unit_id" ISNULL AND
|
jbe@532
|
864 "area_id" ISNULL AND
|
jbe@536
|
865 "policy_id" ISNULL AND
|
jbe@532
|
866 "issue_id" ISNULL AND
|
jbe@532
|
867 "state" ISNULL AND
|
jbe@532
|
868 "initiative_id" ISNULL AND
|
jbe@532
|
869 "draft_id" ISNULL AND
|
jbe@532
|
870 "suggestion_id" ISNULL AND
|
jbe@532
|
871 "boolean_value" NOTNULL AND
|
jbe@532
|
872 "numeric_value" ISNULL AND
|
jbe@532
|
873 "text_value" ISNULL AND
|
jbe@532
|
874 "old_text_value" ISNULL ));
|
jbe@532
|
875 ALTER TABLE "event" ADD CONSTRAINT "constr_for_member_name_updated" CHECK (
|
jbe@532
|
876 "event" != 'member_name_updated' OR (
|
jbe@532
|
877 "member_id" NOTNULL AND
|
jbe@532
|
878 "other_member_id" ISNULL AND
|
jbe@532
|
879 "scope" ISNULL AND
|
jbe@532
|
880 "unit_id" ISNULL AND
|
jbe@532
|
881 "area_id" ISNULL AND
|
jbe@536
|
882 "policy_id" ISNULL AND
|
jbe@532
|
883 "issue_id" ISNULL AND
|
jbe@532
|
884 "state" ISNULL AND
|
jbe@532
|
885 "initiative_id" ISNULL AND
|
jbe@532
|
886 "draft_id" ISNULL AND
|
jbe@532
|
887 "suggestion_id" ISNULL AND
|
jbe@532
|
888 "boolean_value" ISNULL AND
|
jbe@532
|
889 "numeric_value" ISNULL AND
|
jbe@532
|
890 "text_value" NOTNULL AND
|
jbe@532
|
891 "old_text_value" NOTNULL ));
|
jbe@532
|
892 ALTER TABLE "event" ADD CONSTRAINT "constr_for_interest" CHECK (
|
jbe@532
|
893 "event" != 'interest' OR (
|
jbe@532
|
894 "member_id" NOTNULL AND
|
jbe@532
|
895 "other_member_id" ISNULL AND
|
jbe@532
|
896 "scope" ISNULL AND
|
jbe@532
|
897 "unit_id" NOTNULL AND
|
jbe@532
|
898 "area_id" NOTNULL AND
|
jbe@536
|
899 "policy_id" NOTNULL AND
|
jbe@532
|
900 "issue_id" NOTNULL AND
|
jbe@532
|
901 "state" NOTNULL AND
|
jbe@532
|
902 "initiative_id" ISNULL AND
|
jbe@532
|
903 "draft_id" ISNULL AND
|
jbe@532
|
904 "suggestion_id" ISNULL AND
|
jbe@532
|
905 "boolean_value" NOTNULL AND
|
jbe@532
|
906 "numeric_value" ISNULL AND
|
jbe@532
|
907 "text_value" ISNULL AND
|
jbe@532
|
908 "old_text_value" ISNULL ));
|
jbe@532
|
909 ALTER TABLE "event" ADD CONSTRAINT "constr_for_initiator" CHECK (
|
jbe@532
|
910 "event" != 'initiator' OR (
|
jbe@532
|
911 "member_id" NOTNULL AND
|
jbe@532
|
912 "other_member_id" ISNULL AND
|
jbe@532
|
913 "scope" ISNULL AND
|
jbe@532
|
914 "unit_id" NOTNULL AND
|
jbe@532
|
915 "area_id" NOTNULL AND
|
jbe@536
|
916 "policy_id" NOTNULL AND
|
jbe@532
|
917 "issue_id" NOTNULL AND
|
jbe@532
|
918 "state" NOTNULL AND
|
jbe@532
|
919 "initiative_id" NOTNULL AND
|
jbe@532
|
920 "draft_id" ISNULL AND
|
jbe@532
|
921 "suggestion_id" ISNULL AND
|
jbe@532
|
922 "boolean_value" NOTNULL AND
|
jbe@532
|
923 "numeric_value" ISNULL AND
|
jbe@532
|
924 "text_value" ISNULL AND
|
jbe@532
|
925 "old_text_value" ISNULL ));
|
jbe@532
|
926 ALTER TABLE "event" ADD CONSTRAINT "constr_for_support" CHECK (
|
jbe@532
|
927 "event" != 'support' OR (
|
jbe@532
|
928 "member_id" NOTNULL AND
|
jbe@532
|
929 "other_member_id" ISNULL AND
|
jbe@532
|
930 "scope" ISNULL AND
|
jbe@532
|
931 "unit_id" NOTNULL AND
|
jbe@532
|
932 "area_id" NOTNULL AND
|
jbe@536
|
933 "policy_id" NOTNULL AND
|
jbe@532
|
934 "issue_id" NOTNULL AND
|
jbe@532
|
935 "state" NOTNULL AND
|
jbe@532
|
936 "initiative_id" NOTNULL AND
|
jbe@532
|
937 ("draft_id" NOTNULL) = ("boolean_value" = TRUE) AND
|
jbe@532
|
938 "suggestion_id" ISNULL AND
|
jbe@532
|
939 "boolean_value" NOTNULL AND
|
jbe@532
|
940 "numeric_value" ISNULL AND
|
jbe@532
|
941 "text_value" ISNULL AND
|
jbe@532
|
942 "old_text_value" ISNULL ));
|
jbe@532
|
943 ALTER TABLE "event" ADD CONSTRAINT "constr_for_support_updated" CHECK (
|
jbe@532
|
944 "event" != 'support_updated' OR (
|
jbe@532
|
945 "member_id" NOTNULL AND
|
jbe@532
|
946 "other_member_id" ISNULL AND
|
jbe@532
|
947 "scope" ISNULL AND
|
jbe@532
|
948 "unit_id" NOTNULL AND
|
jbe@532
|
949 "area_id" NOTNULL AND
|
jbe@536
|
950 "policy_id" NOTNULL AND
|
jbe@532
|
951 "issue_id" NOTNULL AND
|
jbe@532
|
952 "state" NOTNULL AND
|
jbe@532
|
953 "initiative_id" NOTNULL AND
|
jbe@532
|
954 "draft_id" NOTNULL AND
|
jbe@532
|
955 "suggestion_id" ISNULL AND
|
jbe@532
|
956 "boolean_value" ISNULL AND
|
jbe@532
|
957 "numeric_value" ISNULL AND
|
jbe@532
|
958 "text_value" ISNULL AND
|
jbe@532
|
959 "old_text_value" ISNULL ));
|
jbe@532
|
960 ALTER TABLE "event" ADD CONSTRAINT "constr_for_suggestion_rated" CHECK (
|
jbe@532
|
961 "event" != 'suggestion_rated' OR (
|
jbe@532
|
962 "member_id" NOTNULL AND
|
jbe@532
|
963 "other_member_id" ISNULL AND
|
jbe@532
|
964 "scope" ISNULL AND
|
jbe@532
|
965 "unit_id" NOTNULL AND
|
jbe@532
|
966 "area_id" NOTNULL AND
|
jbe@536
|
967 "policy_id" NOTNULL AND
|
jbe@532
|
968 "issue_id" NOTNULL AND
|
jbe@532
|
969 "state" NOTNULL AND
|
jbe@532
|
970 "initiative_id" NOTNULL AND
|
jbe@532
|
971 "draft_id" ISNULL AND
|
jbe@532
|
972 "suggestion_id" NOTNULL AND
|
jbe@532
|
973 ("boolean_value" NOTNULL) = ("numeric_value" != 0) AND
|
jbe@532
|
974 "numeric_value" NOTNULL AND
|
jbe@532
|
975 "numeric_value" IN (-2, -1, 0, 1, 2) AND
|
jbe@532
|
976 "text_value" ISNULL AND
|
jbe@532
|
977 "old_text_value" ISNULL ));
|
jbe@532
|
978 ALTER TABLE "event" ADD CONSTRAINT "constr_for_delegation" CHECK (
|
jbe@532
|
979 "event" != 'delegation' OR (
|
jbe@532
|
980 "member_id" NOTNULL AND
|
jbe@532
|
981 ("other_member_id" NOTNULL) OR ("boolean_value" = FALSE) AND
|
jbe@532
|
982 "scope" NOTNULL AND
|
jbe@532
|
983 "unit_id" NOTNULL AND
|
jbe@532
|
984 ("area_id" NOTNULL) = ("scope" != 'unit'::"delegation_scope") AND
|
jbe@536
|
985 "policy_id" ISNULL AND
|
jbe@532
|
986 ("issue_id" NOTNULL) = ("scope" = 'issue'::"delegation_scope") AND
|
jbe@532
|
987 ("state" NOTNULL) = ("scope" = 'issue'::"delegation_scope") AND
|
jbe@532
|
988 "initiative_id" ISNULL AND
|
jbe@532
|
989 "draft_id" ISNULL AND
|
jbe@532
|
990 "suggestion_id" ISNULL AND
|
jbe@532
|
991 "boolean_value" NOTNULL AND
|
jbe@532
|
992 "numeric_value" ISNULL AND
|
jbe@532
|
993 "text_value" ISNULL AND
|
jbe@532
|
994 "old_text_value" ISNULL ));
|
jbe@532
|
995 ALTER TABLE "event" ADD CONSTRAINT "constr_for_contact" CHECK (
|
jbe@532
|
996 "event" != 'contact' OR (
|
jbe@532
|
997 "member_id" NOTNULL AND
|
jbe@532
|
998 "other_member_id" NOTNULL AND
|
jbe@532
|
999 "scope" ISNULL AND
|
jbe@532
|
1000 "unit_id" ISNULL AND
|
jbe@532
|
1001 "area_id" ISNULL AND
|
jbe@536
|
1002 "policy_id" ISNULL AND
|
jbe@532
|
1003 "issue_id" ISNULL AND
|
jbe@532
|
1004 "state" ISNULL AND
|
jbe@532
|
1005 "initiative_id" ISNULL AND
|
jbe@532
|
1006 "draft_id" ISNULL AND
|
jbe@532
|
1007 "suggestion_id" ISNULL AND
|
jbe@532
|
1008 "boolean_value" NOTNULL AND
|
jbe@532
|
1009 "numeric_value" ISNULL AND
|
jbe@532
|
1010 "text_value" ISNULL AND
|
jbe@532
|
1011 "old_text_value" ISNULL ));
|
jbe@532
|
1012
|
jbe@532
|
1013
|
jbe@534
|
1014 ALTER TABLE "notification_event_sent" RENAME TO "event_processed";
|
jbe@534
|
1015 ALTER INDEX "notification_event_sent_singleton_idx" RENAME TO "event_processed_singleton_idx";
|
jbe@534
|
1016
|
jbe@534
|
1017 COMMENT ON TABLE "event_processed" IS 'This table stores one row with the last event_id, for which event handlers have been executed (e.g. notifications having been sent out)';
|
jbe@534
|
1018 COMMENT ON INDEX "event_processed_singleton_idx" IS 'This index ensures that "event_processed" only contains one row maximum.';
|
jbe@534
|
1019
|
jbe@534
|
1020
|
jbe@537
|
1021 CREATE FUNCTION "write_event_unit_trigger"()
|
jbe@537
|
1022 RETURNS TRIGGER
|
jbe@537
|
1023 LANGUAGE 'plpgsql' VOLATILE AS $$
|
jbe@538
|
1024 DECLARE
|
jbe@538
|
1025 "event_v" "event_type";
|
jbe@537
|
1026 BEGIN
|
jbe@538
|
1027 IF TG_OP = 'UPDATE' THEN
|
jbe@538
|
1028 IF OLD."active" = FALSE AND NEW."active" = FALSE THEN
|
jbe@538
|
1029 RETURN NULL;
|
jbe@547
|
1030 --ELSIF OLD."active" = FALSE AND NEW."active" = TRUE THEN
|
jbe@547
|
1031 -- "event_v" := 'unit_created';
|
jbe@547
|
1032 --ELSIF OLD."active" = TRUE AND NEW."active" = FALSE THEN
|
jbe@554
|
1033 -- "event_v" := 'unit_deleted';
|
jbe@546
|
1034 ELSIF OLD != NEW THEN
|
jbe@546
|
1035 "event_v" := 'unit_updated';
|
jbe@538
|
1036 ELSE
|
jbe@546
|
1037 RETURN NULL;
|
jbe@538
|
1038 END IF;
|
jbe@538
|
1039 ELSE
|
jbe@538
|
1040 "event_v" := 'unit_created';
|
jbe@538
|
1041 END IF;
|
jbe@538
|
1042 INSERT INTO "event" ("event", "unit_id") VALUES ("event_v", NEW."id");
|
jbe@537
|
1043 RETURN NULL;
|
jbe@537
|
1044 END;
|
jbe@537
|
1045 $$;
|
jbe@537
|
1046
|
jbe@537
|
1047 CREATE TRIGGER "write_event_unit" AFTER INSERT OR UPDATE ON "unit"
|
jbe@537
|
1048 FOR EACH ROW EXECUTE PROCEDURE "write_event_unit_trigger"();
|
jbe@537
|
1049
|
jbe@537
|
1050 COMMENT ON FUNCTION "write_event_unit_trigger"() IS 'Implementation of trigger "write_event_unit" on table "unit"';
|
jbe@537
|
1051 COMMENT ON TRIGGER "write_event_unit" ON "unit" IS 'Create entry in "event" table on new or changed/disabled units';
|
jbe@537
|
1052
|
jbe@537
|
1053
|
jbe@537
|
1054 CREATE FUNCTION "write_event_area_trigger"()
|
jbe@537
|
1055 RETURNS TRIGGER
|
jbe@537
|
1056 LANGUAGE 'plpgsql' VOLATILE AS $$
|
jbe@538
|
1057 DECLARE
|
jbe@538
|
1058 "event_v" "event_type";
|
jbe@537
|
1059 BEGIN
|
jbe@538
|
1060 IF TG_OP = 'UPDATE' THEN
|
jbe@538
|
1061 IF OLD."active" = FALSE AND NEW."active" = FALSE THEN
|
jbe@538
|
1062 RETURN NULL;
|
jbe@547
|
1063 --ELSIF OLD."active" = FALSE AND NEW."active" = TRUE THEN
|
jbe@547
|
1064 -- "event_v" := 'area_created';
|
jbe@547
|
1065 --ELSIF OLD."active" = TRUE AND NEW."active" = FALSE THEN
|
jbe@554
|
1066 -- "event_v" := 'area_deleted';
|
jbe@546
|
1067 ELSIF OLD != NEW THEN
|
jbe@546
|
1068 "event_v" := 'area_updated';
|
jbe@538
|
1069 ELSE
|
jbe@546
|
1070 RETURN NULL;
|
jbe@538
|
1071 END IF;
|
jbe@538
|
1072 ELSE
|
jbe@538
|
1073 "event_v" := 'area_created';
|
jbe@538
|
1074 END IF;
|
jbe@538
|
1075 INSERT INTO "event" ("event", "area_id") VALUES ("event_v", NEW."id");
|
jbe@537
|
1076 RETURN NULL;
|
jbe@537
|
1077 END;
|
jbe@537
|
1078 $$;
|
jbe@537
|
1079
|
jbe@537
|
1080 CREATE TRIGGER "write_event_area" AFTER INSERT OR UPDATE ON "area"
|
jbe@537
|
1081 FOR EACH ROW EXECUTE PROCEDURE "write_event_area_trigger"();
|
jbe@537
|
1082
|
jbe@537
|
1083 COMMENT ON FUNCTION "write_event_area_trigger"() IS 'Implementation of trigger "write_event_area" on table "area"';
|
jbe@537
|
1084 COMMENT ON TRIGGER "write_event_area" ON "area" IS 'Create entry in "event" table on new or changed/disabled areas';
|
jbe@537
|
1085
|
jbe@537
|
1086
|
jbe@537
|
1087 CREATE FUNCTION "write_event_policy_trigger"()
|
jbe@537
|
1088 RETURNS TRIGGER
|
jbe@537
|
1089 LANGUAGE 'plpgsql' VOLATILE AS $$
|
jbe@538
|
1090 DECLARE
|
jbe@538
|
1091 "event_v" "event_type";
|
jbe@537
|
1092 BEGIN
|
jbe@538
|
1093 IF TG_OP = 'UPDATE' THEN
|
jbe@538
|
1094 IF OLD."active" = FALSE AND NEW."active" = FALSE THEN
|
jbe@538
|
1095 RETURN NULL;
|
jbe@547
|
1096 --ELSIF OLD."active" = FALSE AND NEW."active" = TRUE THEN
|
jbe@547
|
1097 -- "event_v" := 'policy_created';
|
jbe@547
|
1098 --ELSIF OLD."active" = TRUE AND NEW."active" = FALSE THEN
|
jbe@554
|
1099 -- "event_v" := 'policy_deleted';
|
jbe@546
|
1100 ELSIF OLD != NEW THEN
|
jbe@546
|
1101 "event_v" := 'policy_updated';
|
jbe@538
|
1102 ELSE
|
jbe@546
|
1103 RETURN NULL;
|
jbe@538
|
1104 END IF;
|
jbe@538
|
1105 ELSE
|
jbe@538
|
1106 "event_v" := 'policy_created';
|
jbe@538
|
1107 END IF;
|
jbe@538
|
1108 INSERT INTO "event" ("event", "policy_id") VALUES ("event_v", NEW."id");
|
jbe@537
|
1109 RETURN NULL;
|
jbe@537
|
1110 END;
|
jbe@537
|
1111 $$;
|
jbe@537
|
1112
|
jbe@537
|
1113 CREATE TRIGGER "write_event_policy" AFTER INSERT OR UPDATE ON "policy"
|
jbe@537
|
1114 FOR EACH ROW EXECUTE PROCEDURE "write_event_policy_trigger"();
|
jbe@537
|
1115
|
jbe@537
|
1116 COMMENT ON FUNCTION "write_event_policy_trigger"() IS 'Implementation of trigger "write_event_policy" on table "policy"';
|
jbe@537
|
1117 COMMENT ON TRIGGER "write_event_policy" ON "policy" IS 'Create entry in "event" table on new or changed/disabled policies';
|
jbe@537
|
1118
|
jbe@537
|
1119
|
jbe@532
|
1120 CREATE OR REPLACE FUNCTION "write_event_issue_state_changed_trigger"()
|
jbe@532
|
1121 RETURNS TRIGGER
|
jbe@532
|
1122 LANGUAGE 'plpgsql' VOLATILE AS $$
|
jbe@532
|
1123 DECLARE
|
jbe@532
|
1124 "area_row" "area"%ROWTYPE;
|
jbe@532
|
1125 BEGIN
|
jbe@532
|
1126 IF NEW."state" != OLD."state" THEN
|
jbe@532
|
1127 SELECT * INTO "area_row" FROM "area" WHERE "id" = NEW."area_id"
|
jbe@532
|
1128 FOR SHARE;
|
jbe@532
|
1129 INSERT INTO "event" (
|
jbe@532
|
1130 "event",
|
jbe@536
|
1131 "unit_id", "area_id", "policy_id", "issue_id", "state"
|
jbe@532
|
1132 ) VALUES (
|
jbe@532
|
1133 'issue_state_changed',
|
jbe@536
|
1134 "area_row"."unit_id", NEW."area_id", NEW."policy_id",
|
jbe@536
|
1135 NEW."id", NEW."state"
|
jbe@532
|
1136 );
|
jbe@532
|
1137 END IF;
|
jbe@532
|
1138 RETURN NULL;
|
jbe@532
|
1139 END;
|
jbe@532
|
1140 $$;
|
jbe@532
|
1141
|
jbe@532
|
1142
|
jbe@532
|
1143 CREATE OR REPLACE FUNCTION "write_event_initiative_or_draft_created_trigger"()
|
jbe@532
|
1144 RETURNS TRIGGER
|
jbe@532
|
1145 LANGUAGE 'plpgsql' VOLATILE AS $$
|
jbe@532
|
1146 DECLARE
|
jbe@532
|
1147 "initiative_row" "initiative"%ROWTYPE;
|
jbe@532
|
1148 "issue_row" "issue"%ROWTYPE;
|
jbe@532
|
1149 "area_row" "area"%ROWTYPE;
|
jbe@532
|
1150 "event_v" "event_type";
|
jbe@532
|
1151 BEGIN
|
jbe@532
|
1152 SELECT * INTO "initiative_row" FROM "initiative"
|
jbe@532
|
1153 WHERE "id" = NEW."initiative_id" FOR SHARE;
|
jbe@532
|
1154 SELECT * INTO "issue_row" FROM "issue"
|
jbe@532
|
1155 WHERE "id" = "initiative_row"."issue_id" FOR SHARE;
|
jbe@532
|
1156 SELECT * INTO "area_row" FROM "area"
|
jbe@532
|
1157 WHERE "id" = "issue_row"."area_id" FOR SHARE;
|
jbe@532
|
1158 IF EXISTS (
|
jbe@532
|
1159 SELECT NULL FROM "draft"
|
jbe@532
|
1160 WHERE "initiative_id" = NEW."initiative_id" AND "id" != NEW."id"
|
jbe@532
|
1161 FOR SHARE
|
jbe@532
|
1162 ) THEN
|
jbe@532
|
1163 "event_v" := 'new_draft_created';
|
jbe@532
|
1164 ELSE
|
jbe@532
|
1165 IF EXISTS (
|
jbe@532
|
1166 SELECT NULL FROM "initiative"
|
jbe@532
|
1167 WHERE "issue_id" = "initiative_row"."issue_id"
|
jbe@532
|
1168 AND "id" != "initiative_row"."id"
|
jbe@532
|
1169 FOR SHARE
|
jbe@532
|
1170 ) THEN
|
jbe@532
|
1171 "event_v" := 'initiative_created_in_existing_issue';
|
jbe@532
|
1172 ELSE
|
jbe@532
|
1173 "event_v" := 'initiative_created_in_new_issue';
|
jbe@532
|
1174 END IF;
|
jbe@532
|
1175 END IF;
|
jbe@532
|
1176 INSERT INTO "event" (
|
jbe@532
|
1177 "event", "member_id",
|
jbe@536
|
1178 "unit_id", "area_id", "policy_id", "issue_id", "state",
|
jbe@532
|
1179 "initiative_id", "draft_id"
|
jbe@532
|
1180 ) VALUES (
|
jbe@532
|
1181 "event_v", NEW."author_id",
|
jbe@536
|
1182 "area_row"."unit_id", "issue_row"."area_id", "issue_row"."policy_id",
|
jbe@532
|
1183 "initiative_row"."issue_id", "issue_row"."state",
|
jbe@532
|
1184 NEW."initiative_id", NEW."id"
|
jbe@532
|
1185 );
|
jbe@532
|
1186 RETURN NULL;
|
jbe@532
|
1187 END;
|
jbe@532
|
1188 $$;
|
jbe@532
|
1189
|
jbe@532
|
1190
|
jbe@532
|
1191 CREATE OR REPLACE FUNCTION "write_event_initiative_revoked_trigger"()
|
jbe@532
|
1192 RETURNS TRIGGER
|
jbe@532
|
1193 LANGUAGE 'plpgsql' VOLATILE AS $$
|
jbe@532
|
1194 DECLARE
|
jbe@532
|
1195 "issue_row" "issue"%ROWTYPE;
|
jbe@532
|
1196 "area_row" "area"%ROWTYPE;
|
jbe@532
|
1197 "draft_id_v" "draft"."id"%TYPE;
|
jbe@532
|
1198 BEGIN
|
jbe@532
|
1199 IF OLD."revoked" ISNULL AND NEW."revoked" NOTNULL THEN
|
jbe@532
|
1200 SELECT * INTO "issue_row" FROM "issue"
|
jbe@532
|
1201 WHERE "id" = NEW."issue_id" FOR SHARE;
|
jbe@532
|
1202 SELECT * INTO "area_row" FROM "area"
|
jbe@532
|
1203 WHERE "id" = "issue_row"."area_id" FOR SHARE;
|
jbe@532
|
1204 SELECT "id" INTO "draft_id_v" FROM "current_draft"
|
jbe@532
|
1205 WHERE "initiative_id" = NEW."id" FOR SHARE;
|
jbe@532
|
1206 INSERT INTO "event" (
|
jbe@532
|
1207 "event", "member_id",
|
jbe@536
|
1208 "unit_id", "area_id", "policy_id", "issue_id", "state",
|
jbe@532
|
1209 "initiative_id", "draft_id"
|
jbe@532
|
1210 ) VALUES (
|
jbe@532
|
1211 'initiative_revoked', NEW."revoked_by_member_id",
|
jbe@532
|
1212 "area_row"."unit_id", "issue_row"."area_id",
|
jbe@536
|
1213 "issue_row"."policy_id",
|
jbe@532
|
1214 NEW."issue_id", "issue_row"."state",
|
jbe@532
|
1215 NEW."id", "draft_id_v"
|
jbe@532
|
1216 );
|
jbe@532
|
1217 END IF;
|
jbe@532
|
1218 RETURN NULL;
|
jbe@532
|
1219 END;
|
jbe@532
|
1220 $$;
|
jbe@532
|
1221
|
jbe@532
|
1222
|
jbe@532
|
1223 CREATE OR REPLACE FUNCTION "write_event_suggestion_created_trigger"()
|
jbe@532
|
1224 RETURNS TRIGGER
|
jbe@532
|
1225 LANGUAGE 'plpgsql' VOLATILE AS $$
|
jbe@532
|
1226 DECLARE
|
jbe@532
|
1227 "initiative_row" "initiative"%ROWTYPE;
|
jbe@532
|
1228 "issue_row" "issue"%ROWTYPE;
|
jbe@532
|
1229 "area_row" "area"%ROWTYPE;
|
jbe@532
|
1230 BEGIN
|
jbe@532
|
1231 SELECT * INTO "initiative_row" FROM "initiative"
|
jbe@532
|
1232 WHERE "id" = NEW."initiative_id" FOR SHARE;
|
jbe@532
|
1233 SELECT * INTO "issue_row" FROM "issue"
|
jbe@532
|
1234 WHERE "id" = "initiative_row"."issue_id" FOR SHARE;
|
jbe@532
|
1235 SELECT * INTO "area_row" FROM "area"
|
jbe@532
|
1236 WHERE "id" = "issue_row"."area_id" FOR SHARE;
|
jbe@532
|
1237 INSERT INTO "event" (
|
jbe@532
|
1238 "event", "member_id",
|
jbe@536
|
1239 "unit_id", "area_id", "policy_id", "issue_id", "state",
|
jbe@532
|
1240 "initiative_id", "suggestion_id"
|
jbe@532
|
1241 ) VALUES (
|
jbe@532
|
1242 'suggestion_created', NEW."author_id",
|
jbe@536
|
1243 "area_row"."unit_id", "issue_row"."area_id", "issue_row"."policy_id",
|
jbe@532
|
1244 "initiative_row"."issue_id", "issue_row"."state",
|
jbe@532
|
1245 NEW."initiative_id", NEW."id"
|
jbe@532
|
1246 );
|
jbe@532
|
1247 RETURN NULL;
|
jbe@532
|
1248 END;
|
jbe@532
|
1249 $$;
|
jbe@532
|
1250
|
jbe@532
|
1251
|
jbe@532
|
1252 CREATE FUNCTION "write_event_suggestion_removed_trigger"()
|
jbe@532
|
1253 RETURNS TRIGGER
|
jbe@532
|
1254 LANGUAGE 'plpgsql' VOLATILE AS $$
|
jbe@532
|
1255 DECLARE
|
jbe@532
|
1256 "initiative_row" "initiative"%ROWTYPE;
|
jbe@532
|
1257 "issue_row" "issue"%ROWTYPE;
|
jbe@532
|
1258 "area_row" "area"%ROWTYPE;
|
jbe@532
|
1259 BEGIN
|
jbe@532
|
1260 SELECT * INTO "initiative_row" FROM "initiative"
|
jbe@532
|
1261 WHERE "id" = OLD."initiative_id" FOR SHARE;
|
jbe@532
|
1262 IF "initiative_row"."id" NOTNULL THEN
|
jbe@532
|
1263 SELECT * INTO "issue_row" FROM "issue"
|
jbe@532
|
1264 WHERE "id" = "initiative_row"."issue_id" FOR SHARE;
|
jbe@532
|
1265 SELECT * INTO "area_row" FROM "area"
|
jbe@532
|
1266 WHERE "id" = "issue_row"."area_id" FOR SHARE;
|
jbe@532
|
1267 INSERT INTO "event" (
|
jbe@532
|
1268 "event",
|
jbe@536
|
1269 "unit_id", "area_id", "policy_id", "issue_id", "state",
|
jbe@532
|
1270 "initiative_id", "suggestion_id"
|
jbe@532
|
1271 ) VALUES (
|
jbe@554
|
1272 'suggestion_deleted',
|
jbe@532
|
1273 "area_row"."unit_id", "issue_row"."area_id",
|
jbe@536
|
1274 "issue_row"."policy_id",
|
jbe@532
|
1275 "initiative_row"."issue_id", "issue_row"."state",
|
jbe@532
|
1276 OLD."initiative_id", OLD."id"
|
jbe@532
|
1277 );
|
jbe@532
|
1278 END IF;
|
jbe@532
|
1279 RETURN NULL;
|
jbe@532
|
1280 END;
|
jbe@532
|
1281 $$;
|
jbe@532
|
1282
|
jbe@532
|
1283 CREATE TRIGGER "write_event_suggestion_removed"
|
jbe@532
|
1284 AFTER DELETE ON "suggestion" FOR EACH ROW EXECUTE PROCEDURE
|
jbe@532
|
1285 "write_event_suggestion_removed_trigger"();
|
jbe@532
|
1286
|
jbe@532
|
1287 COMMENT ON FUNCTION "write_event_suggestion_removed_trigger"() IS 'Implementation of trigger "write_event_suggestion_removed" on table "issue"';
|
jbe@532
|
1288 COMMENT ON TRIGGER "write_event_suggestion_removed" ON "suggestion" IS 'Create entry in "event" table on suggestion creation';
|
jbe@532
|
1289
|
jbe@532
|
1290
|
jbe@532
|
1291 CREATE FUNCTION "write_event_member_trigger"()
|
jbe@532
|
1292 RETURNS TRIGGER
|
jbe@532
|
1293 LANGUAGE 'plpgsql' VOLATILE AS $$
|
jbe@532
|
1294 BEGIN
|
jbe@532
|
1295 IF TG_OP = 'INSERT' THEN
|
jbe@552
|
1296 IF NEW."activated" NOTNULL AND NEW."deleted" ISNULL THEN
|
jbe@532
|
1297 INSERT INTO "event" ("event", "member_id")
|
jbe@532
|
1298 VALUES ('member_activated', NEW."id");
|
jbe@532
|
1299 END IF;
|
jbe@532
|
1300 IF NEW."active" THEN
|
jbe@532
|
1301 INSERT INTO "event" ("event", "member_id", "boolean_value")
|
jbe@532
|
1302 VALUES ('member_active', NEW."id", TRUE);
|
jbe@532
|
1303 END IF;
|
jbe@532
|
1304 ELSIF TG_OP = 'UPDATE' THEN
|
jbe@532
|
1305 IF OLD."id" != NEW."id" THEN
|
jbe@532
|
1306 RAISE EXCEPTION 'Cannot change member ID';
|
jbe@532
|
1307 END IF;
|
jbe@552
|
1308 IF
|
jbe@552
|
1309 (OLD."activated" ISNULL OR OLD."deleted" NOTNULL) AND
|
jbe@552
|
1310 NEW."activated" NOTNULL AND NEW."deleted" ISNULL
|
jbe@552
|
1311 THEN
|
jbe@552
|
1312 INSERT INTO "event" ("event", "member_id")
|
jbe@552
|
1313 VALUES ('member_activated', NEW."id");
|
jbe@552
|
1314 END IF;
|
jbe@552
|
1315 IF OLD."active" != NEW."active" THEN
|
jbe@552
|
1316 INSERT INTO "event" ("event", "member_id", "boolean_value") VALUES (
|
jbe@552
|
1317 'member_active', NEW."id", NEW."active"
|
jbe@552
|
1318 );
|
jbe@552
|
1319 END IF;
|
jbe@532
|
1320 IF OLD."name" != NEW."name" THEN
|
jbe@532
|
1321 INSERT INTO "event" (
|
jbe@532
|
1322 "event", "member_id", "text_value", "old_text_value"
|
jbe@532
|
1323 ) VALUES (
|
jbe@532
|
1324 'member_name_updated', NEW."id", NEW."name", OLD."name"
|
jbe@532
|
1325 );
|
jbe@532
|
1326 END IF;
|
jbe@532
|
1327 IF
|
jbe@552
|
1328 OLD."activated" NOTNULL AND OLD."deleted" ISNULL AND
|
jbe@552
|
1329 (NEW."activated" ISNULL OR NEW."deleted" NOTNULL)
|
jbe@532
|
1330 THEN
|
jbe@532
|
1331 INSERT INTO "event" ("event", "member_id")
|
jbe@554
|
1332 VALUES ('member_deleted', NEW."id");
|
jbe@532
|
1333 END IF;
|
jbe@532
|
1334 END IF;
|
jbe@532
|
1335 RETURN NULL;
|
jbe@532
|
1336 END;
|
jbe@532
|
1337 $$;
|
jbe@532
|
1338
|
jbe@532
|
1339 CREATE TRIGGER "write_event_member"
|
jbe@532
|
1340 AFTER INSERT OR UPDATE ON "member" FOR EACH ROW EXECUTE PROCEDURE
|
jbe@532
|
1341 "write_event_member_trigger"();
|
jbe@532
|
1342
|
jbe@532
|
1343 COMMENT ON FUNCTION "write_event_member_trigger"() IS 'Implementation of trigger "write_event_member" on table "member"';
|
jbe@532
|
1344 COMMENT ON TRIGGER "write_event_member" ON "member" IS 'Create entries in "event" table on insertion to member table';
|
jbe@532
|
1345
|
jbe@532
|
1346
|
jbe@532
|
1347 CREATE FUNCTION "write_event_member_profile_updated_trigger"()
|
jbe@532
|
1348 RETURNS TRIGGER
|
jbe@532
|
1349 LANGUAGE 'plpgsql' VOLATILE AS $$
|
jbe@532
|
1350 BEGIN
|
jbe@532
|
1351 IF TG_OP = 'DELETE' OR TG_OP = 'UPDATE' THEN
|
jbe@532
|
1352 IF EXISTS (SELECT NULL FROM "member" WHERE "id" = OLD."member_id") THEN
|
jbe@532
|
1353 INSERT INTO "event" ("event", "member_id") VALUES (
|
jbe@532
|
1354 'member_profile_updated', OLD."member_id"
|
jbe@532
|
1355 );
|
jbe@532
|
1356 END IF;
|
jbe@532
|
1357 END IF;
|
jbe@532
|
1358 IF TG_OP = 'UPDATE' THEN
|
jbe@532
|
1359 IF OLD."member_id" = NEW."member_id" THEN
|
jbe@532
|
1360 RETURN NULL;
|
jbe@532
|
1361 END IF;
|
jbe@532
|
1362 END IF;
|
jbe@532
|
1363 IF TG_OP = 'INSERT' OR TG_OP = 'UPDATE' THEN
|
jbe@532
|
1364 INSERT INTO "event" ("event", "member_id") VALUES (
|
jbe@532
|
1365 'member_profile_updated', NEW."member_id"
|
jbe@532
|
1366 );
|
jbe@532
|
1367 END IF;
|
jbe@532
|
1368 RETURN NULL;
|
jbe@532
|
1369 END;
|
jbe@532
|
1370 $$;
|
jbe@532
|
1371
|
jbe@532
|
1372 CREATE TRIGGER "write_event_member_profile_updated"
|
jbe@532
|
1373 AFTER INSERT OR UPDATE OR DELETE ON "member_profile"
|
jbe@532
|
1374 FOR EACH ROW EXECUTE PROCEDURE
|
jbe@532
|
1375 "write_event_member_profile_updated_trigger"();
|
jbe@532
|
1376
|
jbe@532
|
1377 COMMENT ON FUNCTION "write_event_member_profile_updated_trigger"() IS 'Implementation of trigger "write_event_member_profile_updated" on table "member_profile"';
|
jbe@532
|
1378 COMMENT ON TRIGGER "write_event_member_profile_updated" ON "member_profile" IS 'Creates entries in "event" table on member profile update';
|
jbe@532
|
1379
|
jbe@532
|
1380
|
jbe@532
|
1381 CREATE FUNCTION "write_event_member_image_updated_trigger"()
|
jbe@532
|
1382 RETURNS TRIGGER
|
jbe@532
|
1383 LANGUAGE 'plpgsql' VOLATILE AS $$
|
jbe@532
|
1384 BEGIN
|
jbe@532
|
1385 IF TG_OP = 'DELETE' OR TG_OP = 'UPDATE' THEN
|
jbe@532
|
1386 IF NOT OLD."scaled" THEN
|
jbe@532
|
1387 IF EXISTS (SELECT NULL FROM "member" WHERE "id" = OLD."member_id") THEN
|
jbe@532
|
1388 INSERT INTO "event" ("event", "member_id") VALUES (
|
jbe@532
|
1389 'member_image_updated', OLD."member_id"
|
jbe@532
|
1390 );
|
jbe@532
|
1391 END IF;
|
jbe@532
|
1392 END IF;
|
jbe@532
|
1393 END IF;
|
jbe@532
|
1394 IF TG_OP = 'UPDATE' THEN
|
jbe@532
|
1395 IF
|
jbe@532
|
1396 OLD."member_id" = NEW."member_id" AND
|
jbe@532
|
1397 OLD."scaled" = NEW."scaled"
|
jbe@532
|
1398 THEN
|
jbe@532
|
1399 RETURN NULL;
|
jbe@532
|
1400 END IF;
|
jbe@532
|
1401 END IF;
|
jbe@532
|
1402 IF TG_OP = 'INSERT' OR TG_OP = 'UPDATE' THEN
|
jbe@532
|
1403 IF NOT NEW."scaled" THEN
|
jbe@532
|
1404 INSERT INTO "event" ("event", "member_id") VALUES (
|
jbe@532
|
1405 'member_image_updated', NEW."member_id"
|
jbe@532
|
1406 );
|
jbe@532
|
1407 END IF;
|
jbe@532
|
1408 END IF;
|
jbe@532
|
1409 RETURN NULL;
|
jbe@532
|
1410 END;
|
jbe@532
|
1411 $$;
|
jbe@532
|
1412
|
jbe@532
|
1413 CREATE TRIGGER "write_event_member_image_updated"
|
jbe@532
|
1414 AFTER INSERT OR UPDATE OR DELETE ON "member_image"
|
jbe@532
|
1415 FOR EACH ROW EXECUTE PROCEDURE
|
jbe@532
|
1416 "write_event_member_image_updated_trigger"();
|
jbe@532
|
1417
|
jbe@532
|
1418 COMMENT ON FUNCTION "write_event_member_image_updated_trigger"() IS 'Implementation of trigger "write_event_member_image_updated" on table "member_image"';
|
jbe@532
|
1419 COMMENT ON TRIGGER "write_event_member_image_updated" ON "member_image" IS 'Creates entries in "event" table on member image update';
|
jbe@532
|
1420
|
jbe@532
|
1421
|
jbe@532
|
1422 CREATE FUNCTION "write_event_interest_trigger"()
|
jbe@532
|
1423 RETURNS TRIGGER
|
jbe@532
|
1424 LANGUAGE 'plpgsql' VOLATILE AS $$
|
jbe@532
|
1425 DECLARE
|
jbe@532
|
1426 "issue_row" "issue"%ROWTYPE;
|
jbe@532
|
1427 "area_row" "area"%ROWTYPE;
|
jbe@532
|
1428 BEGIN
|
jbe@532
|
1429 IF TG_OP = 'UPDATE' THEN
|
jbe@532
|
1430 IF OLD = NEW THEN
|
jbe@532
|
1431 RETURN NULL;
|
jbe@532
|
1432 END IF;
|
jbe@532
|
1433 END IF;
|
jbe@532
|
1434 IF TG_OP = 'DELETE' OR TG_OP = 'UPDATE' THEN
|
jbe@532
|
1435 SELECT * INTO "issue_row" FROM "issue"
|
jbe@532
|
1436 WHERE "id" = OLD."issue_id" FOR SHARE;
|
jbe@532
|
1437 SELECT * INTO "area_row" FROM "area"
|
jbe@532
|
1438 WHERE "id" = "issue_row"."area_id" FOR SHARE;
|
jbe@532
|
1439 IF "issue_row"."id" NOTNULL THEN
|
jbe@532
|
1440 INSERT INTO "event" (
|
jbe@532
|
1441 "event", "member_id",
|
jbe@536
|
1442 "unit_id", "area_id", "policy_id", "issue_id", "state",
|
jbe@532
|
1443 "boolean_value"
|
jbe@532
|
1444 ) VALUES (
|
jbe@532
|
1445 'interest', OLD."member_id",
|
jbe@532
|
1446 "area_row"."unit_id", "issue_row"."area_id",
|
jbe@536
|
1447 "issue_row"."policy_id",
|
jbe@532
|
1448 OLD."issue_id", "issue_row"."state",
|
jbe@532
|
1449 FALSE
|
jbe@532
|
1450 );
|
jbe@532
|
1451 END IF;
|
jbe@532
|
1452 END IF;
|
jbe@532
|
1453 IF TG_OP = 'INSERT' OR TG_OP = 'UPDATE' THEN
|
jbe@532
|
1454 SELECT * INTO "issue_row" FROM "issue"
|
jbe@532
|
1455 WHERE "id" = NEW."issue_id" FOR SHARE;
|
jbe@532
|
1456 SELECT * INTO "area_row" FROM "area"
|
jbe@532
|
1457 WHERE "id" = "issue_row"."area_id" FOR SHARE;
|
jbe@532
|
1458 INSERT INTO "event" (
|
jbe@532
|
1459 "event", "member_id",
|
jbe@536
|
1460 "unit_id", "area_id", "policy_id", "issue_id", "state",
|
jbe@532
|
1461 "boolean_value"
|
jbe@532
|
1462 ) VALUES (
|
jbe@532
|
1463 'interest', NEW."member_id",
|
jbe@532
|
1464 "area_row"."unit_id", "issue_row"."area_id",
|
jbe@536
|
1465 "issue_row"."policy_id",
|
jbe@532
|
1466 NEW."issue_id", "issue_row"."state",
|
jbe@532
|
1467 TRUE
|
jbe@532
|
1468 );
|
jbe@532
|
1469 END IF;
|
jbe@532
|
1470 RETURN NULL;
|
jbe@532
|
1471 END;
|
jbe@532
|
1472 $$;
|
jbe@532
|
1473
|
jbe@532
|
1474 CREATE TRIGGER "write_event_interest"
|
jbe@532
|
1475 AFTER INSERT OR UPDATE OR DELETE ON "interest" FOR EACH ROW EXECUTE PROCEDURE
|
jbe@532
|
1476 "write_event_interest_trigger"();
|
jbe@532
|
1477
|
jbe@532
|
1478 COMMENT ON FUNCTION "write_event_interest_trigger"() IS 'Implementation of trigger "write_event_interest_inserted" on table "interest"';
|
jbe@532
|
1479 COMMENT ON TRIGGER "write_event_interest" ON "interest" IS 'Create entry in "event" table on adding or removing interest';
|
jbe@532
|
1480
|
jbe@532
|
1481
|
jbe@532
|
1482 CREATE FUNCTION "write_event_initiator_trigger"()
|
jbe@532
|
1483 RETURNS TRIGGER
|
jbe@532
|
1484 LANGUAGE 'plpgsql' VOLATILE AS $$
|
jbe@532
|
1485 DECLARE
|
jbe@532
|
1486 "initiative_row" "initiative"%ROWTYPE;
|
jbe@532
|
1487 "issue_row" "issue"%ROWTYPE;
|
jbe@532
|
1488 "area_row" "area"%ROWTYPE;
|
jbe@549
|
1489 "accepted_v" BOOLEAN = FALSE;
|
jbe@549
|
1490 "rejected_v" BOOLEAN = FALSE;
|
jbe@532
|
1491 BEGIN
|
jbe@532
|
1492 IF TG_OP = 'UPDATE' THEN
|
jbe@532
|
1493 IF
|
jbe@532
|
1494 OLD."initiative_id" = NEW."initiative_id" AND
|
jbe@549
|
1495 OLD."member_id" = NEW."member_id"
|
jbe@532
|
1496 THEN
|
jbe@549
|
1497 IF
|
jbe@549
|
1498 coalesce(OLD."accepted", FALSE) = coalesce(NEW."accepted", FALSE)
|
jbe@549
|
1499 THEN
|
jbe@549
|
1500 RETURN NULL;
|
jbe@549
|
1501 END IF;
|
jbe@549
|
1502 IF coalesce(NEW."accepted", FALSE) = TRUE THEN
|
jbe@549
|
1503 "accepted_v" := TRUE;
|
jbe@549
|
1504 ELSE
|
jbe@549
|
1505 "rejected_v" := TRUE;
|
jbe@549
|
1506 END IF;
|
jbe@532
|
1507 END IF;
|
jbe@532
|
1508 END IF;
|
jbe@532
|
1509 IF (TG_OP = 'DELETE' OR TG_OP = 'UPDATE') AND NOT "accepted_v" THEN
|
jbe@532
|
1510 IF coalesce(OLD."accepted", FALSE) = TRUE THEN
|
jbe@532
|
1511 SELECT * INTO "initiative_row" FROM "initiative"
|
jbe@532
|
1512 WHERE "id" = OLD."initiative_id" FOR SHARE;
|
jbe@532
|
1513 IF "initiative_row"."id" NOTNULL THEN
|
jbe@532
|
1514 SELECT * INTO "issue_row" FROM "issue"
|
jbe@532
|
1515 WHERE "id" = "initiative_row"."issue_id" FOR SHARE;
|
jbe@532
|
1516 SELECT * INTO "area_row" FROM "area"
|
jbe@532
|
1517 WHERE "id" = "issue_row"."area_id" FOR SHARE;
|
jbe@532
|
1518 INSERT INTO "event" (
|
jbe@532
|
1519 "event", "member_id",
|
jbe@536
|
1520 "unit_id", "area_id", "policy_id", "issue_id", "state",
|
jbe@532
|
1521 "initiative_id", "boolean_value"
|
jbe@532
|
1522 ) VALUES (
|
jbe@532
|
1523 'initiator', OLD."member_id",
|
jbe@532
|
1524 "area_row"."unit_id", "issue_row"."area_id",
|
jbe@536
|
1525 "issue_row"."policy_id",
|
jbe@532
|
1526 "issue_row"."id", "issue_row"."state",
|
jbe@532
|
1527 OLD."initiative_id", FALSE
|
jbe@532
|
1528 );
|
jbe@532
|
1529 END IF;
|
jbe@532
|
1530 END IF;
|
jbe@532
|
1531 END IF;
|
jbe@532
|
1532 IF TG_OP = 'UPDATE' AND NOT "rejected_v" THEN
|
jbe@532
|
1533 IF coalesce(NEW."accepted", FALSE) = TRUE THEN
|
jbe@532
|
1534 SELECT * INTO "initiative_row" FROM "initiative"
|
jbe@532
|
1535 WHERE "id" = NEW."initiative_id" FOR SHARE;
|
jbe@532
|
1536 SELECT * INTO "issue_row" FROM "issue"
|
jbe@532
|
1537 WHERE "id" = "initiative_row"."issue_id" FOR SHARE;
|
jbe@532
|
1538 SELECT * INTO "area_row" FROM "area"
|
jbe@532
|
1539 WHERE "id" = "issue_row"."area_id" FOR SHARE;
|
jbe@532
|
1540 INSERT INTO "event" (
|
jbe@532
|
1541 "event", "member_id",
|
jbe@536
|
1542 "unit_id", "area_id", "policy_id", "issue_id", "state",
|
jbe@532
|
1543 "initiative_id", "boolean_value"
|
jbe@532
|
1544 ) VALUES (
|
jbe@532
|
1545 'initiator', NEW."member_id",
|
jbe@532
|
1546 "area_row"."unit_id", "issue_row"."area_id",
|
jbe@536
|
1547 "issue_row"."policy_id",
|
jbe@532
|
1548 "issue_row"."id", "issue_row"."state",
|
jbe@532
|
1549 NEW."initiative_id", TRUE
|
jbe@532
|
1550 );
|
jbe@532
|
1551 END IF;
|
jbe@532
|
1552 END IF;
|
jbe@532
|
1553 RETURN NULL;
|
jbe@532
|
1554 END;
|
jbe@532
|
1555 $$;
|
jbe@532
|
1556
|
jbe@532
|
1557 CREATE TRIGGER "write_event_initiator"
|
jbe@532
|
1558 AFTER UPDATE OR DELETE ON "initiator" FOR EACH ROW EXECUTE PROCEDURE
|
jbe@532
|
1559 "write_event_initiator_trigger"();
|
jbe@532
|
1560
|
jbe@532
|
1561 COMMENT ON FUNCTION "write_event_initiator_trigger"() IS 'Implementation of trigger "write_event_initiator" on table "initiator"';
|
jbe@532
|
1562 COMMENT ON TRIGGER "write_event_initiator" ON "initiator" IS 'Create entry in "event" table when accepting or removing initiatorship (NOTE: trigger does not fire on INSERT to avoid events on initiative creation)';
|
jbe@532
|
1563
|
jbe@532
|
1564
|
jbe@532
|
1565 CREATE FUNCTION "write_event_support_trigger"()
|
jbe@532
|
1566 RETURNS TRIGGER
|
jbe@532
|
1567 LANGUAGE 'plpgsql' VOLATILE AS $$
|
jbe@532
|
1568 DECLARE
|
jbe@532
|
1569 "issue_row" "issue"%ROWTYPE;
|
jbe@532
|
1570 "area_row" "area"%ROWTYPE;
|
jbe@532
|
1571 BEGIN
|
jbe@532
|
1572 IF TG_OP = 'UPDATE' THEN
|
jbe@532
|
1573 IF
|
jbe@532
|
1574 OLD."initiative_id" = NEW."initiative_id" AND
|
jbe@532
|
1575 OLD."member_id" = NEW."member_id"
|
jbe@532
|
1576 THEN
|
jbe@532
|
1577 IF OLD."draft_id" != NEW."draft_id" THEN
|
jbe@532
|
1578 SELECT * INTO "issue_row" FROM "issue"
|
jbe@532
|
1579 WHERE "id" = NEW."issue_id" FOR SHARE;
|
jbe@532
|
1580 SELECT * INTO "area_row" FROM "area"
|
jbe@532
|
1581 WHERE "id" = "issue_row"."area_id" FOR SHARE;
|
jbe@532
|
1582 INSERT INTO "event" (
|
jbe@532
|
1583 "event", "member_id",
|
jbe@536
|
1584 "unit_id", "area_id", "policy_id", "issue_id", "state",
|
jbe@532
|
1585 "initiative_id", "draft_id"
|
jbe@532
|
1586 ) VALUES (
|
jbe@532
|
1587 'support_updated', NEW."member_id",
|
jbe@532
|
1588 "area_row"."unit_id", "issue_row"."area_id",
|
jbe@536
|
1589 "issue_row"."policy_id",
|
jbe@532
|
1590 "issue_row"."id", "issue_row"."state",
|
jbe@532
|
1591 NEW."initiative_id", NEW."draft_id"
|
jbe@532
|
1592 );
|
jbe@532
|
1593 END IF;
|
jbe@532
|
1594 RETURN NULL;
|
jbe@532
|
1595 END IF;
|
jbe@532
|
1596 END IF;
|
jbe@532
|
1597 IF TG_OP = 'DELETE' OR TG_OP = 'UPDATE' THEN
|
jbe@532
|
1598 IF EXISTS (
|
jbe@532
|
1599 SELECT NULL FROM "initiative" WHERE "id" = OLD."initiative_id"
|
jbe@532
|
1600 FOR SHARE
|
jbe@532
|
1601 ) THEN
|
jbe@532
|
1602 SELECT * INTO "issue_row" FROM "issue"
|
jbe@532
|
1603 WHERE "id" = OLD."issue_id" FOR SHARE;
|
jbe@532
|
1604 SELECT * INTO "area_row" FROM "area"
|
jbe@532
|
1605 WHERE "id" = "issue_row"."area_id" FOR SHARE;
|
jbe@532
|
1606 INSERT INTO "event" (
|
jbe@532
|
1607 "event", "member_id",
|
jbe@536
|
1608 "unit_id", "area_id", "policy_id", "issue_id", "state",
|
jbe@535
|
1609 "initiative_id", "boolean_value"
|
jbe@532
|
1610 ) VALUES (
|
jbe@532
|
1611 'support', OLD."member_id",
|
jbe@532
|
1612 "area_row"."unit_id", "issue_row"."area_id",
|
jbe@536
|
1613 "issue_row"."policy_id",
|
jbe@532
|
1614 "issue_row"."id", "issue_row"."state",
|
jbe@535
|
1615 OLD."initiative_id", FALSE
|
jbe@532
|
1616 );
|
jbe@532
|
1617 END IF;
|
jbe@532
|
1618 END IF;
|
jbe@532
|
1619 IF TG_OP = 'INSERT' OR TG_OP = 'UPDATE' THEN
|
jbe@532
|
1620 SELECT * INTO "issue_row" FROM "issue"
|
jbe@532
|
1621 WHERE "id" = NEW."issue_id" FOR SHARE;
|
jbe@532
|
1622 SELECT * INTO "area_row" FROM "area"
|
jbe@532
|
1623 WHERE "id" = "issue_row"."area_id" FOR SHARE;
|
jbe@532
|
1624 INSERT INTO "event" (
|
jbe@532
|
1625 "event", "member_id",
|
jbe@536
|
1626 "unit_id", "area_id", "policy_id", "issue_id", "state",
|
jbe@532
|
1627 "initiative_id", "draft_id", "boolean_value"
|
jbe@532
|
1628 ) VALUES (
|
jbe@532
|
1629 'support', NEW."member_id",
|
jbe@532
|
1630 "area_row"."unit_id", "issue_row"."area_id",
|
jbe@536
|
1631 "issue_row"."policy_id",
|
jbe@532
|
1632 "issue_row"."id", "issue_row"."state",
|
jbe@532
|
1633 NEW."initiative_id", NEW."draft_id", TRUE
|
jbe@532
|
1634 );
|
jbe@532
|
1635 END IF;
|
jbe@532
|
1636 RETURN NULL;
|
jbe@532
|
1637 END;
|
jbe@532
|
1638 $$;
|
jbe@532
|
1639
|
jbe@532
|
1640 CREATE TRIGGER "write_event_support"
|
jbe@532
|
1641 AFTER INSERT OR UPDATE OR DELETE ON "supporter" FOR EACH ROW EXECUTE PROCEDURE
|
jbe@532
|
1642 "write_event_support_trigger"();
|
jbe@532
|
1643
|
jbe@532
|
1644 COMMENT ON FUNCTION "write_event_support_trigger"() IS 'Implementation of trigger "write_event_support" on table "supporter"';
|
jbe@532
|
1645 COMMENT ON TRIGGER "write_event_support" ON "supporter" IS 'Create entry in "event" table when adding, updating, or removing support';
|
jbe@532
|
1646
|
jbe@532
|
1647
|
jbe@532
|
1648 CREATE FUNCTION "write_event_suggestion_rated_trigger"()
|
jbe@532
|
1649 RETURNS TRIGGER
|
jbe@532
|
1650 LANGUAGE 'plpgsql' VOLATILE AS $$
|
jbe@532
|
1651 DECLARE
|
jbe@532
|
1652 "same_pkey_v" BOOLEAN = FALSE;
|
jbe@532
|
1653 "initiative_row" "initiative"%ROWTYPE;
|
jbe@532
|
1654 "issue_row" "issue"%ROWTYPE;
|
jbe@532
|
1655 "area_row" "area"%ROWTYPE;
|
jbe@532
|
1656 BEGIN
|
jbe@532
|
1657 IF TG_OP = 'UPDATE' THEN
|
jbe@532
|
1658 IF
|
jbe@532
|
1659 OLD."suggestion_id" = NEW."suggestion_id" AND
|
jbe@532
|
1660 OLD."member_id" = NEW."member_id"
|
jbe@532
|
1661 THEN
|
jbe@532
|
1662 IF
|
jbe@532
|
1663 OLD."degree" = NEW."degree" AND
|
jbe@532
|
1664 OLD."fulfilled" = NEW."fulfilled"
|
jbe@532
|
1665 THEN
|
jbe@532
|
1666 RETURN NULL;
|
jbe@532
|
1667 END IF;
|
jbe@532
|
1668 "same_pkey_v" := TRUE;
|
jbe@532
|
1669 END IF;
|
jbe@532
|
1670 END IF;
|
jbe@532
|
1671 IF (TG_OP = 'DELETE' OR TG_OP = 'UPDATE') AND NOT "same_pkey_v" THEN
|
jbe@532
|
1672 IF EXISTS (
|
jbe@532
|
1673 SELECT NULL FROM "suggestion" WHERE "id" = OLD."suggestion_id"
|
jbe@532
|
1674 FOR SHARE
|
jbe@532
|
1675 ) THEN
|
jbe@532
|
1676 SELECT * INTO "initiative_row" FROM "initiative"
|
jbe@532
|
1677 WHERE "id" = OLD."initiative_id" FOR SHARE;
|
jbe@532
|
1678 SELECT * INTO "issue_row" FROM "issue"
|
jbe@532
|
1679 WHERE "id" = "initiative_row"."issue_id" FOR SHARE;
|
jbe@532
|
1680 SELECT * INTO "area_row" FROM "area"
|
jbe@532
|
1681 WHERE "id" = "issue_row"."area_id" FOR SHARE;
|
jbe@532
|
1682 INSERT INTO "event" (
|
jbe@532
|
1683 "event", "member_id",
|
jbe@536
|
1684 "unit_id", "area_id", "policy_id", "issue_id", "state",
|
jbe@532
|
1685 "initiative_id", "suggestion_id",
|
jbe@532
|
1686 "boolean_value", "numeric_value"
|
jbe@532
|
1687 ) VALUES (
|
jbe@532
|
1688 'suggestion_rated', OLD."member_id",
|
jbe@532
|
1689 "area_row"."unit_id", "issue_row"."area_id",
|
jbe@536
|
1690 "issue_row"."policy_id",
|
jbe@532
|
1691 "initiative_row"."issue_id", "issue_row"."state",
|
jbe@532
|
1692 OLD."initiative_id", OLD."suggestion_id",
|
jbe@532
|
1693 NULL, 0
|
jbe@532
|
1694 );
|
jbe@532
|
1695 END IF;
|
jbe@532
|
1696 END IF;
|
jbe@532
|
1697 IF TG_OP = 'INSERT' OR TG_OP = 'UPDATE' THEN
|
jbe@532
|
1698 SELECT * INTO "initiative_row" FROM "initiative"
|
jbe@532
|
1699 WHERE "id" = NEW."initiative_id" FOR SHARE;
|
jbe@532
|
1700 SELECT * INTO "issue_row" FROM "issue"
|
jbe@532
|
1701 WHERE "id" = "initiative_row"."issue_id" FOR SHARE;
|
jbe@532
|
1702 SELECT * INTO "area_row" FROM "area"
|
jbe@532
|
1703 WHERE "id" = "issue_row"."area_id" FOR SHARE;
|
jbe@532
|
1704 INSERT INTO "event" (
|
jbe@532
|
1705 "event", "member_id",
|
jbe@536
|
1706 "unit_id", "area_id", "policy_id", "issue_id", "state",
|
jbe@532
|
1707 "initiative_id", "suggestion_id",
|
jbe@532
|
1708 "boolean_value", "numeric_value"
|
jbe@532
|
1709 ) VALUES (
|
jbe@532
|
1710 'suggestion_rated', NEW."member_id",
|
jbe@532
|
1711 "area_row"."unit_id", "issue_row"."area_id",
|
jbe@536
|
1712 "issue_row"."policy_id",
|
jbe@532
|
1713 "initiative_row"."issue_id", "issue_row"."state",
|
jbe@532
|
1714 NEW."initiative_id", NEW."suggestion_id",
|
jbe@532
|
1715 NEW."fulfilled", NEW."degree"
|
jbe@532
|
1716 );
|
jbe@532
|
1717 END IF;
|
jbe@532
|
1718 RETURN NULL;
|
jbe@532
|
1719 END;
|
jbe@532
|
1720 $$;
|
jbe@532
|
1721
|
jbe@532
|
1722 CREATE TRIGGER "write_event_suggestion_rated"
|
jbe@532
|
1723 AFTER INSERT OR UPDATE OR DELETE ON "opinion" FOR EACH ROW EXECUTE PROCEDURE
|
jbe@532
|
1724 "write_event_suggestion_rated_trigger"();
|
jbe@532
|
1725
|
jbe@532
|
1726 COMMENT ON FUNCTION "write_event_suggestion_rated_trigger"() IS 'Implementation of trigger "write_event_suggestion_rated" on table "opinion"';
|
jbe@532
|
1727 COMMENT ON TRIGGER "write_event_suggestion_rated" ON "opinion" IS 'Create entry in "event" table when adding, updating, or removing support';
|
jbe@532
|
1728
|
jbe@532
|
1729
|
jbe@532
|
1730 CREATE FUNCTION "write_event_delegation_trigger"()
|
jbe@532
|
1731 RETURNS TRIGGER
|
jbe@532
|
1732 LANGUAGE 'plpgsql' VOLATILE AS $$
|
jbe@532
|
1733 DECLARE
|
jbe@532
|
1734 "issue_row" "issue"%ROWTYPE;
|
jbe@532
|
1735 "area_row" "area"%ROWTYPE;
|
jbe@532
|
1736 BEGIN
|
jbe@532
|
1737 IF TG_OP = 'DELETE' THEN
|
jbe@532
|
1738 IF EXISTS (
|
jbe@532
|
1739 SELECT NULL FROM "member" WHERE "id" = OLD."truster_id"
|
jbe@532
|
1740 ) AND (CASE OLD."scope"
|
jbe@532
|
1741 WHEN 'unit'::"delegation_scope" THEN EXISTS (
|
jbe@532
|
1742 SELECT NULL FROM "unit" WHERE "id" = OLD."unit_id"
|
jbe@532
|
1743 )
|
jbe@532
|
1744 WHEN 'area'::"delegation_scope" THEN EXISTS (
|
jbe@532
|
1745 SELECT NULL FROM "area" WHERE "id" = OLD."area_id"
|
jbe@532
|
1746 )
|
jbe@532
|
1747 WHEN 'issue'::"delegation_scope" THEN EXISTS (
|
jbe@532
|
1748 SELECT NULL FROM "issue" WHERE "id" = OLD."issue_id"
|
jbe@532
|
1749 )
|
jbe@532
|
1750 END) THEN
|
jbe@532
|
1751 SELECT * INTO "issue_row" FROM "issue"
|
jbe@532
|
1752 WHERE "id" = OLD."issue_id" FOR SHARE;
|
jbe@532
|
1753 SELECT * INTO "area_row" FROM "area"
|
jbe@532
|
1754 WHERE "id" = COALESCE(OLD."area_id", "issue_row"."area_id")
|
jbe@532
|
1755 FOR SHARE;
|
jbe@532
|
1756 INSERT INTO "event" (
|
jbe@532
|
1757 "event", "member_id", "scope",
|
jbe@532
|
1758 "unit_id", "area_id", "issue_id", "state",
|
jbe@532
|
1759 "boolean_value"
|
jbe@532
|
1760 ) VALUES (
|
jbe@532
|
1761 'delegation', OLD."truster_id", OLD."scope",
|
jbe@532
|
1762 COALESCE(OLD."unit_id", "area_row"."unit_id"), "area_row"."id",
|
jbe@532
|
1763 OLD."issue_id", "issue_row"."state",
|
jbe@532
|
1764 FALSE
|
jbe@532
|
1765 );
|
jbe@532
|
1766 END IF;
|
jbe@532
|
1767 ELSE
|
jbe@532
|
1768 SELECT * INTO "issue_row" FROM "issue"
|
jbe@532
|
1769 WHERE "id" = NEW."issue_id" FOR SHARE;
|
jbe@532
|
1770 SELECT * INTO "area_row" FROM "area"
|
jbe@532
|
1771 WHERE "id" = COALESCE(NEW."area_id", "issue_row"."area_id")
|
jbe@532
|
1772 FOR SHARE;
|
jbe@532
|
1773 INSERT INTO "event" (
|
jbe@532
|
1774 "event", "member_id", "other_member_id", "scope",
|
jbe@532
|
1775 "unit_id", "area_id", "issue_id", "state",
|
jbe@532
|
1776 "boolean_value"
|
jbe@532
|
1777 ) VALUES (
|
jbe@532
|
1778 'delegation', NEW."truster_id", NEW."trustee_id", NEW."scope",
|
jbe@532
|
1779 COALESCE(NEW."unit_id", "area_row"."unit_id"), "area_row"."id",
|
jbe@532
|
1780 NEW."issue_id", "issue_row"."state",
|
jbe@532
|
1781 TRUE
|
jbe@532
|
1782 );
|
jbe@532
|
1783 END IF;
|
jbe@532
|
1784 RETURN NULL;
|
jbe@532
|
1785 END;
|
jbe@532
|
1786 $$;
|
jbe@532
|
1787
|
jbe@532
|
1788 CREATE TRIGGER "write_event_delegation"
|
jbe@532
|
1789 AFTER INSERT OR UPDATE OR DELETE ON "delegation" FOR EACH ROW EXECUTE PROCEDURE
|
jbe@532
|
1790 "write_event_delegation_trigger"();
|
jbe@532
|
1791
|
jbe@532
|
1792 COMMENT ON FUNCTION "write_event_delegation_trigger"() IS 'Implementation of trigger "write_event_delegation" on table "delegation"';
|
jbe@532
|
1793 COMMENT ON TRIGGER "write_event_delegation" ON "delegation" IS 'Create entry in "event" table when adding, updating, or removing a delegation';
|
jbe@532
|
1794
|
jbe@532
|
1795
|
jbe@532
|
1796 CREATE FUNCTION "write_event_contact_trigger"()
|
jbe@532
|
1797 RETURNS TRIGGER
|
jbe@532
|
1798 LANGUAGE 'plpgsql' VOLATILE AS $$
|
jbe@532
|
1799 BEGIN
|
jbe@532
|
1800 IF TG_OP = 'UPDATE' THEN
|
jbe@532
|
1801 IF
|
jbe@532
|
1802 OLD."member_id" = NEW."member_id" AND
|
jbe@532
|
1803 OLD."other_member_id" = NEW."other_member_id" AND
|
jbe@532
|
1804 OLD."public" = NEW."public"
|
jbe@532
|
1805 THEN
|
jbe@532
|
1806 RETURN NULL;
|
jbe@532
|
1807 END IF;
|
jbe@532
|
1808 END IF;
|
jbe@532
|
1809 IF TG_OP = 'DELETE' OR TG_OP = 'UPDATE' THEN
|
jbe@532
|
1810 IF OLD."public" THEN
|
jbe@532
|
1811 IF EXISTS (
|
jbe@532
|
1812 SELECT NULL FROM "member" WHERE "id" = OLD."member_id"
|
jbe@532
|
1813 FOR SHARE
|
jbe@532
|
1814 ) AND EXISTS (
|
jbe@532
|
1815 SELECT NULL FROM "member" WHERE "id" = OLD."other_member_id"
|
jbe@532
|
1816 FOR SHARE
|
jbe@532
|
1817 ) THEN
|
jbe@532
|
1818 INSERT INTO "event" (
|
jbe@532
|
1819 "event", "member_id", "other_member_id", "boolean_value"
|
jbe@532
|
1820 ) VALUES (
|
jbe@532
|
1821 'contact', OLD."member_id", OLD."other_member_id", FALSE
|
jbe@532
|
1822 );
|
jbe@532
|
1823 END IF;
|
jbe@532
|
1824 END IF;
|
jbe@532
|
1825 END IF;
|
jbe@532
|
1826 IF TG_OP = 'INSERT' OR TG_OP = 'UPDATE' THEN
|
jbe@532
|
1827 IF NEW."public" THEN
|
jbe@532
|
1828 INSERT INTO "event" (
|
jbe@532
|
1829 "event", "member_id", "other_member_id", "boolean_value"
|
jbe@532
|
1830 ) VALUES (
|
jbe@532
|
1831 'contact', NEW."member_id", NEW."other_member_id", TRUE
|
jbe@532
|
1832 );
|
jbe@532
|
1833 END IF;
|
jbe@532
|
1834 END IF;
|
jbe@532
|
1835 RETURN NULL;
|
jbe@532
|
1836 END;
|
jbe@532
|
1837 $$;
|
jbe@532
|
1838
|
jbe@532
|
1839 CREATE TRIGGER "write_event_contact"
|
jbe@532
|
1840 AFTER INSERT OR UPDATE OR DELETE ON "contact" FOR EACH ROW EXECUTE PROCEDURE
|
jbe@532
|
1841 "write_event_contact_trigger"();
|
jbe@532
|
1842
|
jbe@532
|
1843 COMMENT ON FUNCTION "write_event_contact_trigger"() IS 'Implementation of trigger "write_event_contact" on table "contact"';
|
jbe@532
|
1844 COMMENT ON TRIGGER "write_event_contact" ON "contact" IS 'Create entry in "event" table when adding or removing public contacts';
|
jbe@532
|
1845
|
jbe@532
|
1846
|
jbe@532
|
1847 CREATE FUNCTION "send_event_notify_trigger"()
|
jbe@532
|
1848 RETURNS TRIGGER
|
jbe@532
|
1849 LANGUAGE 'plpgsql' VOLATILE AS $$
|
jbe@532
|
1850 BEGIN
|
jbe@532
|
1851 EXECUTE 'NOTIFY "event", ''' || NEW."event" || '''';
|
jbe@532
|
1852 RETURN NULL;
|
jbe@532
|
1853 END;
|
jbe@532
|
1854 $$;
|
jbe@532
|
1855
|
jbe@532
|
1856 CREATE TRIGGER "send_notify"
|
jbe@532
|
1857 AFTER INSERT OR UPDATE ON "event" FOR EACH ROW EXECUTE PROCEDURE
|
jbe@532
|
1858 "send_event_notify_trigger"();
|
jbe@532
|
1859
|
jbe@532
|
1860
|
jbe@532
|
1861 CREATE FUNCTION "delete_extended_scope_tokens_trigger"()
|
jbe@532
|
1862 RETURNS TRIGGER
|
jbe@532
|
1863 LANGUAGE 'plpgsql' VOLATILE AS $$
|
jbe@532
|
1864 DECLARE
|
jbe@532
|
1865 "system_application_row" "system_application"%ROWTYPE;
|
jbe@532
|
1866 BEGIN
|
jbe@532
|
1867 IF OLD."system_application_id" NOTNULL THEN
|
jbe@532
|
1868 SELECT * FROM "system_application" INTO "system_application_row"
|
jbe@532
|
1869 WHERE "id" = OLD."system_application_id";
|
jbe@532
|
1870 DELETE FROM "token"
|
jbe@532
|
1871 WHERE "member_id" = OLD."member_id"
|
jbe@532
|
1872 AND "system_application_id" = OLD."system_application_id"
|
jbe@532
|
1873 AND NOT COALESCE(
|
jbe@532
|
1874 regexp_split_to_array("scope", E'\\s+') <@
|
jbe@532
|
1875 regexp_split_to_array(
|
jbe@532
|
1876 "system_application_row"."automatic_scope", E'\\s+'
|
jbe@532
|
1877 ),
|
jbe@532
|
1878 FALSE
|
jbe@532
|
1879 );
|
jbe@532
|
1880 END IF;
|
jbe@532
|
1881 RETURN OLD;
|
jbe@532
|
1882 END;
|
jbe@532
|
1883 $$;
|
jbe@532
|
1884
|
jbe@532
|
1885 CREATE TRIGGER "delete_extended_scope_tokens"
|
jbe@532
|
1886 BEFORE DELETE ON "member_application" FOR EACH ROW EXECUTE PROCEDURE
|
jbe@532
|
1887 "delete_extended_scope_tokens_trigger"();
|
jbe@532
|
1888
|
jbe@532
|
1889
|
jbe@532
|
1890 CREATE FUNCTION "detach_token_from_session_trigger"()
|
jbe@532
|
1891 RETURNS TRIGGER
|
jbe@532
|
1892 LANGUAGE 'plpgsql' VOLATILE AS $$
|
jbe@532
|
1893 BEGIN
|
jbe@532
|
1894 UPDATE "token" SET "session_id" = NULL
|
jbe@532
|
1895 WHERE "session_id" = OLD."id";
|
jbe@532
|
1896 RETURN OLD;
|
jbe@532
|
1897 END;
|
jbe@532
|
1898 $$;
|
jbe@532
|
1899
|
jbe@532
|
1900 CREATE TRIGGER "detach_token_from_session"
|
jbe@532
|
1901 BEFORE DELETE ON "session" FOR EACH ROW EXECUTE PROCEDURE
|
jbe@532
|
1902 "detach_token_from_session_trigger"();
|
jbe@532
|
1903
|
jbe@532
|
1904
|
jbe@532
|
1905 CREATE FUNCTION "delete_non_detached_scope_with_session_trigger"()
|
jbe@532
|
1906 RETURNS TRIGGER
|
jbe@532
|
1907 LANGUAGE 'plpgsql' VOLATILE AS $$
|
jbe@532
|
1908 BEGIN
|
jbe@532
|
1909 IF NEW."session_id" ISNULL THEN
|
jbe@532
|
1910 SELECT coalesce(string_agg("element", ' '), '') INTO NEW."scope"
|
jbe@532
|
1911 FROM unnest(regexp_split_to_array(NEW."scope", E'\\s+')) AS "element"
|
jbe@532
|
1912 WHERE "element" LIKE '%_detached';
|
jbe@532
|
1913 END IF;
|
jbe@532
|
1914 RETURN NEW;
|
jbe@532
|
1915 END;
|
jbe@532
|
1916 $$;
|
jbe@532
|
1917
|
jbe@532
|
1918 CREATE TRIGGER "delete_non_detached_scope_with_session"
|
jbe@532
|
1919 BEFORE INSERT OR UPDATE ON "token" FOR EACH ROW EXECUTE PROCEDURE
|
jbe@532
|
1920 "delete_non_detached_scope_with_session_trigger"();
|
jbe@532
|
1921
|
jbe@532
|
1922
|
jbe@532
|
1923 CREATE FUNCTION "delete_token_with_empty_scope_trigger"()
|
jbe@532
|
1924 RETURNS TRIGGER
|
jbe@532
|
1925 LANGUAGE 'plpgsql' VOLATILE AS $$
|
jbe@532
|
1926 BEGIN
|
jbe@532
|
1927 IF NEW."scope" = '' THEN
|
jbe@532
|
1928 DELETE FROM "token" WHERE "id" = NEW."id";
|
jbe@532
|
1929 END IF;
|
jbe@532
|
1930 RETURN NULL;
|
jbe@532
|
1931 END;
|
jbe@532
|
1932 $$;
|
jbe@532
|
1933
|
jbe@532
|
1934 CREATE TRIGGER "delete_token_with_empty_scope"
|
jbe@532
|
1935 AFTER INSERT OR UPDATE ON "token" FOR EACH ROW EXECUTE PROCEDURE
|
jbe@532
|
1936 "delete_token_with_empty_scope_trigger"();
|
jbe@532
|
1937
|
jbe@532
|
1938
|
jbe@532
|
1939 CREATE FUNCTION "delete_snapshot_on_partial_delete_trigger"()
|
jbe@532
|
1940 RETURNS TRIGGER
|
jbe@532
|
1941 LANGUAGE 'plpgsql' VOLATILE AS $$
|
jbe@532
|
1942 BEGIN
|
jbe@532
|
1943 IF TG_OP = 'UPDATE' THEN
|
jbe@532
|
1944 IF
|
jbe@532
|
1945 OLD."snapshot_id" = NEW."snapshot_id" AND
|
jbe@532
|
1946 OLD."issue_id" = NEW."issue_id"
|
jbe@532
|
1947 THEN
|
jbe@532
|
1948 RETURN NULL;
|
jbe@532
|
1949 END IF;
|
jbe@532
|
1950 END IF;
|
jbe@532
|
1951 DELETE FROM "snapshot" WHERE "id" = OLD."snapshot_id";
|
jbe@532
|
1952 RETURN NULL;
|
jbe@532
|
1953 END;
|
jbe@532
|
1954 $$;
|
jbe@532
|
1955
|
jbe@532
|
1956 CREATE TRIGGER "delete_snapshot_on_partial_delete"
|
jbe@532
|
1957 AFTER UPDATE OR DELETE ON "snapshot_issue"
|
jbe@532
|
1958 FOR EACH ROW EXECUTE PROCEDURE
|
jbe@532
|
1959 "delete_snapshot_on_partial_delete_trigger"();
|
jbe@532
|
1960
|
jbe@532
|
1961 COMMENT ON FUNCTION "delete_snapshot_on_partial_delete_trigger"() IS 'Implementation of trigger "delete_snapshot_on_partial_delete" on table "snapshot_issue"';
|
jbe@532
|
1962 COMMENT ON TRIGGER "delete_snapshot_on_partial_delete" ON "snapshot_issue" IS 'Deletes whole snapshot if one issue is deleted from the snapshot';
|
jbe@532
|
1963
|
jbe@532
|
1964
|
jbe@532
|
1965 CREATE FUNCTION "copy_current_draft_data"
|
jbe@532
|
1966 ("initiative_id_p" "initiative"."id"%TYPE )
|
jbe@532
|
1967 RETURNS VOID
|
jbe@532
|
1968 LANGUAGE 'plpgsql' VOLATILE AS $$
|
jbe@532
|
1969 BEGIN
|
jbe@532
|
1970 PERFORM NULL FROM "initiative" WHERE "id" = "initiative_id_p"
|
jbe@532
|
1971 FOR UPDATE;
|
jbe@532
|
1972 UPDATE "initiative" SET
|
jbe@532
|
1973 "location" = "draft"."location",
|
jbe@532
|
1974 "draft_text_search_data" = "draft"."text_search_data"
|
jbe@532
|
1975 FROM "current_draft" AS "draft"
|
jbe@532
|
1976 WHERE "initiative"."id" = "initiative_id_p"
|
jbe@532
|
1977 AND "draft"."initiative_id" = "initiative_id_p";
|
jbe@532
|
1978 END;
|
jbe@532
|
1979 $$;
|
jbe@532
|
1980
|
jbe@532
|
1981 COMMENT ON FUNCTION "copy_current_draft_data"
|
jbe@532
|
1982 ( "initiative"."id"%TYPE )
|
jbe@532
|
1983 IS 'Helper function for function "copy_current_draft_data_trigger"';
|
jbe@532
|
1984
|
jbe@532
|
1985
|
jbe@532
|
1986 CREATE FUNCTION "copy_current_draft_data_trigger"()
|
jbe@532
|
1987 RETURNS TRIGGER
|
jbe@532
|
1988 LANGUAGE 'plpgsql' VOLATILE AS $$
|
jbe@532
|
1989 BEGIN
|
jbe@532
|
1990 IF TG_OP='DELETE' THEN
|
jbe@532
|
1991 PERFORM "copy_current_draft_data"(OLD."initiative_id");
|
jbe@532
|
1992 ELSE
|
jbe@532
|
1993 IF TG_OP='UPDATE' THEN
|
jbe@532
|
1994 IF COALESCE(OLD."inititiave_id" != NEW."initiative_id", TRUE) THEN
|
jbe@532
|
1995 PERFORM "copy_current_draft_data"(OLD."initiative_id");
|
jbe@532
|
1996 END IF;
|
jbe@532
|
1997 END IF;
|
jbe@532
|
1998 PERFORM "copy_current_draft_data"(NEW."initiative_id");
|
jbe@532
|
1999 END IF;
|
jbe@532
|
2000 RETURN NULL;
|
jbe@532
|
2001 END;
|
jbe@532
|
2002 $$;
|
jbe@532
|
2003
|
jbe@532
|
2004 CREATE TRIGGER "copy_current_draft_data"
|
jbe@532
|
2005 AFTER INSERT OR UPDATE OR DELETE ON "draft"
|
jbe@532
|
2006 FOR EACH ROW EXECUTE PROCEDURE
|
jbe@532
|
2007 "copy_current_draft_data_trigger"();
|
jbe@532
|
2008
|
jbe@532
|
2009 COMMENT ON FUNCTION "copy_current_draft_data_trigger"() IS 'Implementation of trigger "copy_current_draft_data" on table "draft"';
|
jbe@532
|
2010 COMMENT ON TRIGGER "copy_current_draft_data" ON "draft" IS 'Copy certain fields from most recent "draft" to "initiative"';
|
jbe@532
|
2011
|
jbe@532
|
2012
|
jbe@532
|
2013 CREATE VIEW "area_quorum" AS
|
jbe@532
|
2014 SELECT
|
jbe@532
|
2015 "area"."id" AS "area_id",
|
jbe@532
|
2016 ceil(
|
jbe@532
|
2017 "area"."quorum_standard"::FLOAT8 * "quorum_factor"::FLOAT8 ^ (
|
jbe@532
|
2018 coalesce(
|
jbe@532
|
2019 ( SELECT sum(
|
jbe@532
|
2020 ( extract(epoch from "area"."quorum_time")::FLOAT8 /
|
jbe@532
|
2021 extract(epoch from
|
jbe@532
|
2022 ("issue"."accepted"-"issue"."created") +
|
jbe@532
|
2023 "issue"."discussion_time" +
|
jbe@532
|
2024 "issue"."verification_time" +
|
jbe@532
|
2025 "issue"."voting_time"
|
jbe@532
|
2026 )::FLOAT8
|
jbe@532
|
2027 ) ^ "area"."quorum_exponent"::FLOAT8
|
jbe@532
|
2028 )
|
jbe@532
|
2029 FROM "issue" JOIN "policy"
|
jbe@532
|
2030 ON "issue"."policy_id" = "policy"."id"
|
jbe@532
|
2031 WHERE "issue"."area_id" = "area"."id"
|
jbe@532
|
2032 AND "issue"."accepted" NOTNULL
|
jbe@532
|
2033 AND "issue"."closed" ISNULL
|
jbe@532
|
2034 AND "policy"."polling" = FALSE
|
jbe@532
|
2035 )::FLOAT8, 0::FLOAT8
|
jbe@532
|
2036 ) / "area"."quorum_issues"::FLOAT8 - 1::FLOAT8
|
jbe@532
|
2037 ) * CASE WHEN "area"."quorum_den" ISNULL THEN 1 ELSE (
|
jbe@532
|
2038 SELECT "snapshot"."population"
|
jbe@532
|
2039 FROM "snapshot"
|
jbe@532
|
2040 WHERE "snapshot"."area_id" = "area"."id"
|
jbe@532
|
2041 AND "snapshot"."issue_id" ISNULL
|
jbe@532
|
2042 ORDER BY "snapshot"."id" DESC
|
jbe@532
|
2043 LIMIT 1
|
jbe@532
|
2044 ) END / coalesce("area"."quorum_den", 1)
|
jbe@532
|
2045
|
jbe@532
|
2046 )::INT4 AS "issue_quorum"
|
jbe@532
|
2047 FROM "area";
|
jbe@532
|
2048
|
jbe@532
|
2049 COMMENT ON VIEW "area_quorum" IS 'Area-based quorum considering number of open (accepted) issues';
|
jbe@532
|
2050
|
jbe@532
|
2051
|
jbe@532
|
2052 CREATE VIEW "area_with_unaccepted_issues" AS
|
jbe@532
|
2053 SELECT DISTINCT ON ("area"."id") "area".*
|
jbe@532
|
2054 FROM "area" JOIN "issue" ON "area"."id" = "issue"."area_id"
|
jbe@532
|
2055 WHERE "issue"."state" = 'admission';
|
jbe@532
|
2056
|
jbe@532
|
2057 COMMENT ON VIEW "area_with_unaccepted_issues" IS 'All areas with unaccepted open issues (needed for issue admission system)';
|
jbe@532
|
2058
|
jbe@532
|
2059
|
jbe@532
|
2060 DROP VIEW "area_member_count";
|
jbe@532
|
2061
|
jbe@532
|
2062
|
jbe@532
|
2063 DROP TABLE "membership";
|
jbe@532
|
2064
|
jbe@532
|
2065
|
jbe@532
|
2066 DROP FUNCTION "membership_weight"
|
jbe@532
|
2067 ( "area_id_p" "area"."id"%TYPE,
|
jbe@532
|
2068 "member_id_p" "member"."id"%TYPE );
|
jbe@532
|
2069
|
jbe@532
|
2070
|
jbe@532
|
2071 DROP FUNCTION "membership_weight_with_skipping"
|
jbe@532
|
2072 ( "area_id_p" "area"."id"%TYPE,
|
jbe@532
|
2073 "member_id_p" "member"."id"%TYPE,
|
jbe@532
|
2074 "skip_member_ids_p" INT4[] ); -- TODO: ordering/cascade
|
jbe@532
|
2075
|
jbe@532
|
2076
|
jbe@532
|
2077 CREATE OR REPLACE VIEW "issue_delegation" AS
|
jbe@532
|
2078 SELECT DISTINCT ON ("issue"."id", "delegation"."truster_id")
|
jbe@532
|
2079 "issue"."id" AS "issue_id",
|
jbe@532
|
2080 "delegation"."id",
|
jbe@532
|
2081 "delegation"."truster_id",
|
jbe@532
|
2082 "delegation"."trustee_id",
|
jbe@532
|
2083 "delegation"."scope"
|
jbe@532
|
2084 FROM "issue"
|
jbe@532
|
2085 JOIN "area"
|
jbe@532
|
2086 ON "area"."id" = "issue"."area_id"
|
jbe@532
|
2087 JOIN "delegation"
|
jbe@532
|
2088 ON "delegation"."unit_id" = "area"."unit_id"
|
jbe@532
|
2089 OR "delegation"."area_id" = "area"."id"
|
jbe@532
|
2090 OR "delegation"."issue_id" = "issue"."id"
|
jbe@532
|
2091 JOIN "member"
|
jbe@532
|
2092 ON "delegation"."truster_id" = "member"."id"
|
jbe@556
|
2093 JOIN "privilege"
|
jbe@556
|
2094 ON "area"."unit_id" = "privilege"."unit_id"
|
jbe@556
|
2095 AND "delegation"."truster_id" = "privilege"."member_id"
|
jbe@556
|
2096 WHERE "member"."active" AND "privilege"."voting_right"
|
jbe@532
|
2097 ORDER BY
|
jbe@532
|
2098 "issue"."id",
|
jbe@532
|
2099 "delegation"."truster_id",
|
jbe@532
|
2100 "delegation"."scope" DESC;
|
jbe@532
|
2101
|
jbe@532
|
2102
|
jbe@532
|
2103 CREATE VIEW "unit_member" AS
|
jbe@532
|
2104 SELECT
|
jbe@532
|
2105 "unit"."id" AS "unit_id",
|
jbe@532
|
2106 "member"."id" AS "member_id"
|
jbe@556
|
2107 FROM "privilege"
|
jbe@556
|
2108 JOIN "unit" ON "unit_id" = "privilege"."unit_id"
|
jbe@556
|
2109 JOIN "member" ON "member"."id" = "privilege"."member_id"
|
jbe@556
|
2110 WHERE "privilege"."voting_right" AND "member"."active";
|
jbe@532
|
2111
|
jbe@532
|
2112 COMMENT ON VIEW "unit_member" IS 'Active members with voting right in a unit';
|
jbe@532
|
2113
|
jbe@532
|
2114
|
jbe@532
|
2115 CREATE OR REPLACE VIEW "unit_member_count" AS
|
jbe@532
|
2116 SELECT
|
jbe@532
|
2117 "unit"."id" AS "unit_id",
|
jbe@532
|
2118 count("unit_member"."member_id") AS "member_count"
|
jbe@532
|
2119 FROM "unit" LEFT JOIN "unit_member"
|
jbe@532
|
2120 ON "unit"."id" = "unit_member"."unit_id"
|
jbe@532
|
2121 GROUP BY "unit"."id";
|
jbe@532
|
2122
|
jbe@532
|
2123 COMMENT ON VIEW "unit_member_count" IS 'View used to update "member_count" column of "unit" table';
|
jbe@532
|
2124
|
jbe@532
|
2125
|
jbe@532
|
2126 CREATE OR REPLACE VIEW "opening_draft" AS
|
jbe@532
|
2127 SELECT DISTINCT ON ("initiative_id") * FROM "draft"
|
jbe@532
|
2128 ORDER BY "initiative_id", "id";
|
jbe@532
|
2129
|
jbe@532
|
2130
|
jbe@532
|
2131 CREATE OR REPLACE VIEW "current_draft" AS
|
jbe@532
|
2132 SELECT DISTINCT ON ("initiative_id") * FROM "draft"
|
jbe@532
|
2133 ORDER BY "initiative_id", "id" DESC;
|
jbe@532
|
2134
|
jbe@532
|
2135
|
jbe@532
|
2136 CREATE OR REPLACE VIEW "issue_supporter_in_admission_state" AS
|
jbe@532
|
2137 SELECT
|
jbe@532
|
2138 "area"."unit_id",
|
jbe@532
|
2139 "issue"."area_id",
|
jbe@532
|
2140 "issue"."id" AS "issue_id",
|
jbe@532
|
2141 "supporter"."member_id",
|
jbe@532
|
2142 "direct_interest_snapshot"."weight"
|
jbe@532
|
2143 FROM "issue"
|
jbe@532
|
2144 JOIN "area" ON "area"."id" = "issue"."area_id"
|
jbe@532
|
2145 JOIN "supporter" ON "supporter"."issue_id" = "issue"."id"
|
jbe@532
|
2146 JOIN "direct_interest_snapshot"
|
jbe@532
|
2147 ON "direct_interest_snapshot"."snapshot_id" = "issue"."latest_snapshot_id"
|
jbe@532
|
2148 AND "direct_interest_snapshot"."issue_id" = "issue"."id"
|
jbe@532
|
2149 AND "direct_interest_snapshot"."member_id" = "supporter"."member_id"
|
jbe@532
|
2150 WHERE "issue"."state" = 'admission'::"issue_state";
|
jbe@532
|
2151
|
jbe@532
|
2152
|
jbe@532
|
2153 CREATE OR REPLACE VIEW "individual_suggestion_ranking" AS
|
jbe@532
|
2154 SELECT
|
jbe@532
|
2155 "opinion"."initiative_id",
|
jbe@532
|
2156 "opinion"."member_id",
|
jbe@532
|
2157 "direct_interest_snapshot"."weight",
|
jbe@532
|
2158 CASE WHEN
|
jbe@532
|
2159 ("opinion"."degree" = 2 AND "opinion"."fulfilled" = FALSE) OR
|
jbe@532
|
2160 ("opinion"."degree" = -2 AND "opinion"."fulfilled" = TRUE)
|
jbe@532
|
2161 THEN 1 ELSE
|
jbe@532
|
2162 CASE WHEN
|
jbe@532
|
2163 ("opinion"."degree" = 1 AND "opinion"."fulfilled" = FALSE) OR
|
jbe@532
|
2164 ("opinion"."degree" = -1 AND "opinion"."fulfilled" = TRUE)
|
jbe@532
|
2165 THEN 2 ELSE
|
jbe@532
|
2166 CASE WHEN
|
jbe@532
|
2167 ("opinion"."degree" = 2 AND "opinion"."fulfilled" = TRUE) OR
|
jbe@532
|
2168 ("opinion"."degree" = -2 AND "opinion"."fulfilled" = FALSE)
|
jbe@532
|
2169 THEN 3 ELSE 4 END
|
jbe@532
|
2170 END
|
jbe@532
|
2171 END AS "preference",
|
jbe@532
|
2172 "opinion"."suggestion_id"
|
jbe@532
|
2173 FROM "opinion"
|
jbe@532
|
2174 JOIN "initiative" ON "initiative"."id" = "opinion"."initiative_id"
|
jbe@532
|
2175 JOIN "issue" ON "issue"."id" = "initiative"."issue_id"
|
jbe@532
|
2176 JOIN "direct_interest_snapshot"
|
jbe@532
|
2177 ON "direct_interest_snapshot"."snapshot_id" = "issue"."latest_snapshot_id"
|
jbe@532
|
2178 AND "direct_interest_snapshot"."issue_id" = "issue"."id"
|
jbe@532
|
2179 AND "direct_interest_snapshot"."member_id" = "opinion"."member_id";
|
jbe@532
|
2180
|
jbe@532
|
2181
|
jbe@532
|
2182 CREATE VIEW "expired_session" AS
|
jbe@532
|
2183 SELECT * FROM "session" WHERE now() > "expiry";
|
jbe@532
|
2184
|
jbe@532
|
2185 CREATE RULE "delete" AS ON DELETE TO "expired_session" DO INSTEAD
|
jbe@532
|
2186 DELETE FROM "session" WHERE "id" = OLD."id";
|
jbe@532
|
2187
|
jbe@532
|
2188 COMMENT ON VIEW "expired_session" IS 'View containing all expired sessions where DELETE is possible';
|
jbe@532
|
2189 COMMENT ON RULE "delete" ON "expired_session" IS 'Rule allowing DELETE on rows in "expired_session" view, i.e. DELETE FROM "expired_session"';
|
jbe@532
|
2190
|
jbe@532
|
2191
|
jbe@532
|
2192 CREATE VIEW "expired_token" AS
|
jbe@532
|
2193 SELECT * FROM "token" WHERE now() > "expiry" AND NOT (
|
jbe@532
|
2194 "token_type" = 'authorization' AND "used" AND EXISTS (
|
jbe@532
|
2195 SELECT NULL FROM "token" AS "other"
|
jbe@532
|
2196 WHERE "other"."authorization_token_id" = "id" ) );
|
jbe@532
|
2197
|
jbe@532
|
2198 CREATE RULE "delete" AS ON DELETE TO "expired_token" DO INSTEAD
|
jbe@532
|
2199 DELETE FROM "token" WHERE "id" = OLD."id";
|
jbe@532
|
2200
|
jbe@532
|
2201 COMMENT ON VIEW "expired_token" IS 'View containing all expired tokens where DELETE is possible; Note that used authorization codes must not be deleted if still referred to by other tokens';
|
jbe@532
|
2202
|
jbe@532
|
2203
|
jbe@532
|
2204 CREATE VIEW "unused_snapshot" AS
|
jbe@532
|
2205 SELECT "snapshot".* FROM "snapshot"
|
jbe@532
|
2206 LEFT JOIN "issue"
|
jbe@532
|
2207 ON "snapshot"."id" = "issue"."latest_snapshot_id"
|
jbe@532
|
2208 OR "snapshot"."id" = "issue"."admission_snapshot_id"
|
jbe@532
|
2209 OR "snapshot"."id" = "issue"."half_freeze_snapshot_id"
|
jbe@532
|
2210 OR "snapshot"."id" = "issue"."full_freeze_snapshot_id"
|
jbe@532
|
2211 WHERE "issue"."id" ISNULL;
|
jbe@532
|
2212
|
jbe@532
|
2213 CREATE RULE "delete" AS ON DELETE TO "unused_snapshot" DO INSTEAD
|
jbe@532
|
2214 DELETE FROM "snapshot" WHERE "id" = OLD."id";
|
jbe@532
|
2215
|
jbe@532
|
2216 COMMENT ON VIEW "unused_snapshot" IS 'Snapshots that are not referenced by any issue (either as latest snapshot or as snapshot at phase/state change)';
|
jbe@532
|
2217
|
jbe@532
|
2218
|
jbe@532
|
2219 CREATE VIEW "expired_snapshot" AS
|
jbe@532
|
2220 SELECT "unused_snapshot".* FROM "unused_snapshot" CROSS JOIN "system_setting"
|
jbe@532
|
2221 WHERE "unused_snapshot"."calculated" <
|
jbe@532
|
2222 now() - "system_setting"."snapshot_retention";
|
jbe@532
|
2223
|
jbe@532
|
2224 CREATE RULE "delete" AS ON DELETE TO "expired_snapshot" DO INSTEAD
|
jbe@532
|
2225 DELETE FROM "snapshot" WHERE "id" = OLD."id";
|
jbe@532
|
2226
|
jbe@532
|
2227 COMMENT ON VIEW "expired_snapshot" IS 'Contains "unused_snapshot"s that are older than "system_setting"."snapshot_retention" (for deletion)';
|
jbe@532
|
2228
|
jbe@532
|
2229
|
jbe@532
|
2230 COMMENT ON COLUMN "delegation_chain_row"."participation" IS 'In case of delegation chains for issues: interest; for area and global delegation chains: always null';
|
jbe@532
|
2231
|
jbe@532
|
2232
|
jbe@532
|
2233 CREATE OR REPLACE FUNCTION "delegation_chain"
|
jbe@532
|
2234 ( "member_id_p" "member"."id"%TYPE,
|
jbe@532
|
2235 "unit_id_p" "unit"."id"%TYPE,
|
jbe@532
|
2236 "area_id_p" "area"."id"%TYPE,
|
jbe@532
|
2237 "issue_id_p" "issue"."id"%TYPE,
|
jbe@532
|
2238 "simulate_trustee_id_p" "member"."id"%TYPE DEFAULT NULL,
|
jbe@532
|
2239 "simulate_default_p" BOOLEAN DEFAULT FALSE )
|
jbe@532
|
2240 RETURNS SETOF "delegation_chain_row"
|
jbe@532
|
2241 LANGUAGE 'plpgsql' STABLE AS $$
|
jbe@532
|
2242 DECLARE
|
jbe@532
|
2243 "scope_v" "delegation_scope";
|
jbe@532
|
2244 "unit_id_v" "unit"."id"%TYPE;
|
jbe@532
|
2245 "area_id_v" "area"."id"%TYPE;
|
jbe@532
|
2246 "issue_row" "issue"%ROWTYPE;
|
jbe@532
|
2247 "visited_member_ids" INT4[]; -- "member"."id"%TYPE[]
|
jbe@532
|
2248 "loop_member_id_v" "member"."id"%TYPE;
|
jbe@532
|
2249 "output_row" "delegation_chain_row";
|
jbe@532
|
2250 "output_rows" "delegation_chain_row"[];
|
jbe@532
|
2251 "simulate_v" BOOLEAN;
|
jbe@532
|
2252 "simulate_here_v" BOOLEAN;
|
jbe@532
|
2253 "delegation_row" "delegation"%ROWTYPE;
|
jbe@532
|
2254 "row_count" INT4;
|
jbe@532
|
2255 "i" INT4;
|
jbe@532
|
2256 "loop_v" BOOLEAN;
|
jbe@532
|
2257 BEGIN
|
jbe@532
|
2258 IF "simulate_trustee_id_p" NOTNULL AND "simulate_default_p" THEN
|
jbe@532
|
2259 RAISE EXCEPTION 'Both "simulate_trustee_id_p" is set, and "simulate_default_p" is true';
|
jbe@532
|
2260 END IF;
|
jbe@532
|
2261 IF "simulate_trustee_id_p" NOTNULL OR "simulate_default_p" THEN
|
jbe@532
|
2262 "simulate_v" := TRUE;
|
jbe@532
|
2263 ELSE
|
jbe@532
|
2264 "simulate_v" := FALSE;
|
jbe@532
|
2265 END IF;
|
jbe@532
|
2266 IF
|
jbe@532
|
2267 "unit_id_p" NOTNULL AND
|
jbe@532
|
2268 "area_id_p" ISNULL AND
|
jbe@532
|
2269 "issue_id_p" ISNULL
|
jbe@532
|
2270 THEN
|
jbe@532
|
2271 "scope_v" := 'unit';
|
jbe@532
|
2272 "unit_id_v" := "unit_id_p";
|
jbe@532
|
2273 ELSIF
|
jbe@532
|
2274 "unit_id_p" ISNULL AND
|
jbe@532
|
2275 "area_id_p" NOTNULL AND
|
jbe@532
|
2276 "issue_id_p" ISNULL
|
jbe@532
|
2277 THEN
|
jbe@532
|
2278 "scope_v" := 'area';
|
jbe@532
|
2279 "area_id_v" := "area_id_p";
|
jbe@532
|
2280 SELECT "unit_id" INTO "unit_id_v"
|
jbe@532
|
2281 FROM "area" WHERE "id" = "area_id_v";
|
jbe@532
|
2282 ELSIF
|
jbe@532
|
2283 "unit_id_p" ISNULL AND
|
jbe@532
|
2284 "area_id_p" ISNULL AND
|
jbe@532
|
2285 "issue_id_p" NOTNULL
|
jbe@532
|
2286 THEN
|
jbe@532
|
2287 SELECT INTO "issue_row" * FROM "issue" WHERE "id" = "issue_id_p";
|
jbe@532
|
2288 IF "issue_row"."id" ISNULL THEN
|
jbe@532
|
2289 RETURN;
|
jbe@532
|
2290 END IF;
|
jbe@532
|
2291 IF "issue_row"."closed" NOTNULL THEN
|
jbe@532
|
2292 IF "simulate_v" THEN
|
jbe@532
|
2293 RAISE EXCEPTION 'Tried to simulate delegation chain for closed issue.';
|
jbe@532
|
2294 END IF;
|
jbe@532
|
2295 FOR "output_row" IN
|
jbe@532
|
2296 SELECT * FROM
|
jbe@532
|
2297 "delegation_chain_for_closed_issue"("member_id_p", "issue_id_p")
|
jbe@532
|
2298 LOOP
|
jbe@532
|
2299 RETURN NEXT "output_row";
|
jbe@532
|
2300 END LOOP;
|
jbe@532
|
2301 RETURN;
|
jbe@532
|
2302 END IF;
|
jbe@532
|
2303 "scope_v" := 'issue';
|
jbe@532
|
2304 SELECT "area_id" INTO "area_id_v"
|
jbe@532
|
2305 FROM "issue" WHERE "id" = "issue_id_p";
|
jbe@532
|
2306 SELECT "unit_id" INTO "unit_id_v"
|
jbe@532
|
2307 FROM "area" WHERE "id" = "area_id_v";
|
jbe@532
|
2308 ELSE
|
jbe@532
|
2309 RAISE EXCEPTION 'Exactly one of unit_id_p, area_id_p, or issue_id_p must be NOTNULL.';
|
jbe@532
|
2310 END IF;
|
jbe@532
|
2311 "visited_member_ids" := '{}';
|
jbe@532
|
2312 "loop_member_id_v" := NULL;
|
jbe@532
|
2313 "output_rows" := '{}';
|
jbe@532
|
2314 "output_row"."index" := 0;
|
jbe@532
|
2315 "output_row"."member_id" := "member_id_p";
|
jbe@532
|
2316 "output_row"."member_valid" := TRUE;
|
jbe@532
|
2317 "output_row"."participation" := FALSE;
|
jbe@532
|
2318 "output_row"."overridden" := FALSE;
|
jbe@532
|
2319 "output_row"."disabled_out" := FALSE;
|
jbe@532
|
2320 "output_row"."scope_out" := NULL;
|
jbe@532
|
2321 LOOP
|
jbe@532
|
2322 IF "visited_member_ids" @> ARRAY["output_row"."member_id"] THEN
|
jbe@532
|
2323 "loop_member_id_v" := "output_row"."member_id";
|
jbe@532
|
2324 ELSE
|
jbe@532
|
2325 "visited_member_ids" :=
|
jbe@532
|
2326 "visited_member_ids" || "output_row"."member_id";
|
jbe@532
|
2327 END IF;
|
jbe@532
|
2328 IF "output_row"."participation" ISNULL THEN
|
jbe@532
|
2329 "output_row"."overridden" := NULL;
|
jbe@532
|
2330 ELSIF "output_row"."participation" THEN
|
jbe@532
|
2331 "output_row"."overridden" := TRUE;
|
jbe@532
|
2332 END IF;
|
jbe@532
|
2333 "output_row"."scope_in" := "output_row"."scope_out";
|
jbe@532
|
2334 "output_row"."member_valid" := EXISTS (
|
jbe@556
|
2335 SELECT NULL FROM "member" JOIN "privilege"
|
jbe@556
|
2336 ON "privilege"."member_id" = "member"."id"
|
jbe@556
|
2337 AND "privilege"."unit_id" = "unit_id_v"
|
jbe@532
|
2338 WHERE "id" = "output_row"."member_id"
|
jbe@556
|
2339 AND "member"."active" AND "privilege"."voting_right"
|
jbe@532
|
2340 );
|
jbe@532
|
2341 "simulate_here_v" := (
|
jbe@532
|
2342 "simulate_v" AND
|
jbe@532
|
2343 "output_row"."member_id" = "member_id_p"
|
jbe@532
|
2344 );
|
jbe@532
|
2345 "delegation_row" := ROW(NULL);
|
jbe@532
|
2346 IF "output_row"."member_valid" OR "simulate_here_v" THEN
|
jbe@532
|
2347 IF "scope_v" = 'unit' THEN
|
jbe@532
|
2348 IF NOT "simulate_here_v" THEN
|
jbe@532
|
2349 SELECT * INTO "delegation_row" FROM "delegation"
|
jbe@532
|
2350 WHERE "truster_id" = "output_row"."member_id"
|
jbe@532
|
2351 AND "unit_id" = "unit_id_v";
|
jbe@532
|
2352 END IF;
|
jbe@532
|
2353 ELSIF "scope_v" = 'area' THEN
|
jbe@532
|
2354 IF "simulate_here_v" THEN
|
jbe@532
|
2355 IF "simulate_trustee_id_p" ISNULL THEN
|
jbe@532
|
2356 SELECT * INTO "delegation_row" FROM "delegation"
|
jbe@532
|
2357 WHERE "truster_id" = "output_row"."member_id"
|
jbe@532
|
2358 AND "unit_id" = "unit_id_v";
|
jbe@532
|
2359 END IF;
|
jbe@532
|
2360 ELSE
|
jbe@532
|
2361 SELECT * INTO "delegation_row" FROM "delegation"
|
jbe@532
|
2362 WHERE "truster_id" = "output_row"."member_id"
|
jbe@532
|
2363 AND (
|
jbe@532
|
2364 "unit_id" = "unit_id_v" OR
|
jbe@532
|
2365 "area_id" = "area_id_v"
|
jbe@532
|
2366 )
|
jbe@532
|
2367 ORDER BY "scope" DESC;
|
jbe@532
|
2368 END IF;
|
jbe@532
|
2369 ELSIF "scope_v" = 'issue' THEN
|
jbe@532
|
2370 IF "issue_row"."fully_frozen" ISNULL THEN
|
jbe@532
|
2371 "output_row"."participation" := EXISTS (
|
jbe@532
|
2372 SELECT NULL FROM "interest"
|
jbe@532
|
2373 WHERE "issue_id" = "issue_id_p"
|
jbe@532
|
2374 AND "member_id" = "output_row"."member_id"
|
jbe@532
|
2375 );
|
jbe@532
|
2376 ELSE
|
jbe@532
|
2377 IF "output_row"."member_id" = "member_id_p" THEN
|
jbe@532
|
2378 "output_row"."participation" := EXISTS (
|
jbe@532
|
2379 SELECT NULL FROM "direct_voter"
|
jbe@532
|
2380 WHERE "issue_id" = "issue_id_p"
|
jbe@532
|
2381 AND "member_id" = "output_row"."member_id"
|
jbe@532
|
2382 );
|
jbe@532
|
2383 ELSE
|
jbe@532
|
2384 "output_row"."participation" := NULL;
|
jbe@532
|
2385 END IF;
|
jbe@532
|
2386 END IF;
|
jbe@532
|
2387 IF "simulate_here_v" THEN
|
jbe@532
|
2388 IF "simulate_trustee_id_p" ISNULL THEN
|
jbe@532
|
2389 SELECT * INTO "delegation_row" FROM "delegation"
|
jbe@532
|
2390 WHERE "truster_id" = "output_row"."member_id"
|
jbe@532
|
2391 AND (
|
jbe@532
|
2392 "unit_id" = "unit_id_v" OR
|
jbe@532
|
2393 "area_id" = "area_id_v"
|
jbe@532
|
2394 )
|
jbe@532
|
2395 ORDER BY "scope" DESC;
|
jbe@532
|
2396 END IF;
|
jbe@532
|
2397 ELSE
|
jbe@532
|
2398 SELECT * INTO "delegation_row" FROM "delegation"
|
jbe@532
|
2399 WHERE "truster_id" = "output_row"."member_id"
|
jbe@532
|
2400 AND (
|
jbe@532
|
2401 "unit_id" = "unit_id_v" OR
|
jbe@532
|
2402 "area_id" = "area_id_v" OR
|
jbe@532
|
2403 "issue_id" = "issue_id_p"
|
jbe@532
|
2404 )
|
jbe@532
|
2405 ORDER BY "scope" DESC;
|
jbe@532
|
2406 END IF;
|
jbe@532
|
2407 END IF;
|
jbe@532
|
2408 ELSE
|
jbe@532
|
2409 "output_row"."participation" := FALSE;
|
jbe@532
|
2410 END IF;
|
jbe@532
|
2411 IF "simulate_here_v" AND "simulate_trustee_id_p" NOTNULL THEN
|
jbe@532
|
2412 "output_row"."scope_out" := "scope_v";
|
jbe@532
|
2413 "output_rows" := "output_rows" || "output_row";
|
jbe@532
|
2414 "output_row"."member_id" := "simulate_trustee_id_p";
|
jbe@532
|
2415 ELSIF "delegation_row"."trustee_id" NOTNULL THEN
|
jbe@532
|
2416 "output_row"."scope_out" := "delegation_row"."scope";
|
jbe@532
|
2417 "output_rows" := "output_rows" || "output_row";
|
jbe@532
|
2418 "output_row"."member_id" := "delegation_row"."trustee_id";
|
jbe@532
|
2419 ELSIF "delegation_row"."scope" NOTNULL THEN
|
jbe@532
|
2420 "output_row"."scope_out" := "delegation_row"."scope";
|
jbe@532
|
2421 "output_row"."disabled_out" := TRUE;
|
jbe@532
|
2422 "output_rows" := "output_rows" || "output_row";
|
jbe@532
|
2423 EXIT;
|
jbe@532
|
2424 ELSE
|
jbe@532
|
2425 "output_row"."scope_out" := NULL;
|
jbe@532
|
2426 "output_rows" := "output_rows" || "output_row";
|
jbe@532
|
2427 EXIT;
|
jbe@532
|
2428 END IF;
|
jbe@532
|
2429 EXIT WHEN "loop_member_id_v" NOTNULL;
|
jbe@532
|
2430 "output_row"."index" := "output_row"."index" + 1;
|
jbe@532
|
2431 END LOOP;
|
jbe@532
|
2432 "row_count" := array_upper("output_rows", 1);
|
jbe@532
|
2433 "i" := 1;
|
jbe@532
|
2434 "loop_v" := FALSE;
|
jbe@532
|
2435 LOOP
|
jbe@532
|
2436 "output_row" := "output_rows"["i"];
|
jbe@532
|
2437 EXIT WHEN "output_row" ISNULL; -- NOTE: ISNULL and NOT ... NOTNULL produce different results!
|
jbe@532
|
2438 IF "loop_v" THEN
|
jbe@532
|
2439 IF "i" + 1 = "row_count" THEN
|
jbe@532
|
2440 "output_row"."loop" := 'last';
|
jbe@532
|
2441 ELSIF "i" = "row_count" THEN
|
jbe@532
|
2442 "output_row"."loop" := 'repetition';
|
jbe@532
|
2443 ELSE
|
jbe@532
|
2444 "output_row"."loop" := 'intermediate';
|
jbe@532
|
2445 END IF;
|
jbe@532
|
2446 ELSIF "output_row"."member_id" = "loop_member_id_v" THEN
|
jbe@532
|
2447 "output_row"."loop" := 'first';
|
jbe@532
|
2448 "loop_v" := TRUE;
|
jbe@532
|
2449 END IF;
|
jbe@532
|
2450 IF "scope_v" = 'unit' THEN
|
jbe@532
|
2451 "output_row"."participation" := NULL;
|
jbe@532
|
2452 END IF;
|
jbe@532
|
2453 RETURN NEXT "output_row";
|
jbe@532
|
2454 "i" := "i" + 1;
|
jbe@532
|
2455 END LOOP;
|
jbe@532
|
2456 RETURN;
|
jbe@532
|
2457 END;
|
jbe@532
|
2458 $$;
|
jbe@532
|
2459
|
jbe@532
|
2460
|
jbe@532
|
2461 CREATE OR REPLACE FUNCTION "get_initiatives_for_notification"
|
jbe@532
|
2462 ( "recipient_id_p" "member"."id"%TYPE )
|
jbe@532
|
2463 RETURNS SETOF "initiative_for_notification"
|
jbe@532
|
2464 LANGUAGE 'plpgsql' VOLATILE AS $$
|
jbe@532
|
2465 DECLARE
|
jbe@532
|
2466 "result_row" "initiative_for_notification"%ROWTYPE;
|
jbe@532
|
2467 "last_draft_id_v" "draft"."id"%TYPE;
|
jbe@532
|
2468 "last_suggestion_id_v" "suggestion"."id"%TYPE;
|
jbe@532
|
2469 BEGIN
|
jbe@532
|
2470 PERFORM "require_transaction_isolation"();
|
jbe@532
|
2471 PERFORM NULL FROM "member" WHERE "id" = "recipient_id_p" FOR UPDATE;
|
jbe@532
|
2472 FOR "result_row" IN
|
jbe@532
|
2473 SELECT * FROM "initiative_for_notification"
|
jbe@532
|
2474 WHERE "recipient_id" = "recipient_id_p"
|
jbe@532
|
2475 LOOP
|
jbe@532
|
2476 SELECT "id" INTO "last_draft_id_v" FROM "draft"
|
jbe@532
|
2477 WHERE "draft"."initiative_id" = "result_row"."initiative_id"
|
jbe@532
|
2478 ORDER BY "id" DESC LIMIT 1;
|
jbe@532
|
2479 SELECT "id" INTO "last_suggestion_id_v" FROM "suggestion"
|
jbe@532
|
2480 WHERE "suggestion"."initiative_id" = "result_row"."initiative_id"
|
jbe@532
|
2481 ORDER BY "id" DESC LIMIT 1;
|
jbe@532
|
2482 INSERT INTO "notification_initiative_sent"
|
jbe@532
|
2483 ("member_id", "initiative_id", "last_draft_id", "last_suggestion_id")
|
jbe@532
|
2484 VALUES (
|
jbe@532
|
2485 "recipient_id_p",
|
jbe@532
|
2486 "result_row"."initiative_id",
|
jbe@532
|
2487 "last_draft_id_v",
|
jbe@532
|
2488 "last_suggestion_id_v" )
|
jbe@532
|
2489 ON CONFLICT ("member_id", "initiative_id") DO UPDATE SET
|
jbe@532
|
2490 "last_draft_id" = "last_draft_id_v",
|
jbe@532
|
2491 "last_suggestion_id" = "last_suggestion_id_v";
|
jbe@532
|
2492 RETURN NEXT "result_row";
|
jbe@532
|
2493 END LOOP;
|
jbe@532
|
2494 DELETE FROM "notification_initiative_sent"
|
jbe@532
|
2495 USING "initiative", "issue"
|
jbe@532
|
2496 WHERE "notification_initiative_sent"."member_id" = "recipient_id_p"
|
jbe@532
|
2497 AND "initiative"."id" = "notification_initiative_sent"."initiative_id"
|
jbe@532
|
2498 AND "issue"."id" = "initiative"."issue_id"
|
jbe@532
|
2499 AND ( "issue"."closed" NOTNULL OR "issue"."fully_frozen" NOTNULL );
|
jbe@532
|
2500 UPDATE "member" SET
|
jbe@532
|
2501 "notification_counter" = "notification_counter" + 1,
|
jbe@532
|
2502 "notification_sent" = now()
|
jbe@532
|
2503 WHERE "id" = "recipient_id_p";
|
jbe@532
|
2504 RETURN;
|
jbe@532
|
2505 END;
|
jbe@532
|
2506 $$;
|
jbe@532
|
2507
|
jbe@532
|
2508
|
jbe@532
|
2509 CREATE OR REPLACE FUNCTION "calculate_member_counts"()
|
jbe@532
|
2510 RETURNS VOID
|
jbe@532
|
2511 LANGUAGE 'plpgsql' VOLATILE AS $$
|
jbe@532
|
2512 BEGIN
|
jbe@532
|
2513 PERFORM "require_transaction_isolation"();
|
jbe@532
|
2514 DELETE FROM "member_count";
|
jbe@532
|
2515 INSERT INTO "member_count" ("total_count")
|
jbe@532
|
2516 SELECT "total_count" FROM "member_count_view";
|
jbe@532
|
2517 UPDATE "unit" SET "member_count" = "view"."member_count"
|
jbe@532
|
2518 FROM "unit_member_count" AS "view"
|
jbe@532
|
2519 WHERE "view"."unit_id" = "unit"."id";
|
jbe@532
|
2520 RETURN;
|
jbe@532
|
2521 END;
|
jbe@532
|
2522 $$;
|
jbe@532
|
2523
|
jbe@532
|
2524 COMMENT ON FUNCTION "calculate_member_counts"() IS 'Updates "member_count" table and "member_count" column of table "area" by materializing data from views "member_count_view" and "unit_member_count"';
|
jbe@532
|
2525
|
jbe@532
|
2526
|
jbe@532
|
2527 CREATE FUNCTION "calculate_area_quorum"()
|
jbe@532
|
2528 RETURNS VOID
|
jbe@532
|
2529 LANGUAGE 'plpgsql' VOLATILE AS $$
|
jbe@532
|
2530 BEGIN
|
jbe@532
|
2531 PERFORM "dont_require_transaction_isolation"();
|
jbe@532
|
2532 UPDATE "area" SET "issue_quorum" = "view"."issue_quorum"
|
jbe@532
|
2533 FROM "area_quorum" AS "view"
|
jbe@532
|
2534 WHERE "view"."area_id" = "area"."id";
|
jbe@532
|
2535 RETURN;
|
jbe@532
|
2536 END;
|
jbe@532
|
2537 $$;
|
jbe@532
|
2538
|
jbe@532
|
2539 COMMENT ON FUNCTION "calculate_area_quorum"() IS 'Calculate column "issue_quorum" in table "area" from view "area_quorum"';
|
jbe@532
|
2540
|
jbe@532
|
2541
|
jbe@532
|
2542 DROP VIEW "remaining_harmonic_initiative_weight_summands";
|
jbe@532
|
2543 DROP VIEW "remaining_harmonic_supporter_weight";
|
jbe@532
|
2544
|
jbe@532
|
2545
|
jbe@532
|
2546 CREATE VIEW "remaining_harmonic_supporter_weight" AS
|
jbe@532
|
2547 SELECT
|
jbe@532
|
2548 "direct_interest_snapshot"."snapshot_id",
|
jbe@532
|
2549 "direct_interest_snapshot"."issue_id",
|
jbe@532
|
2550 "direct_interest_snapshot"."member_id",
|
jbe@532
|
2551 "direct_interest_snapshot"."weight" AS "weight_num",
|
jbe@532
|
2552 count("initiative"."id") AS "weight_den"
|
jbe@532
|
2553 FROM "issue"
|
jbe@532
|
2554 JOIN "direct_interest_snapshot"
|
jbe@532
|
2555 ON "issue"."latest_snapshot_id" = "direct_interest_snapshot"."snapshot_id"
|
jbe@532
|
2556 AND "issue"."id" = "direct_interest_snapshot"."issue_id"
|
jbe@532
|
2557 JOIN "initiative"
|
jbe@532
|
2558 ON "issue"."id" = "initiative"."issue_id"
|
jbe@532
|
2559 AND "initiative"."harmonic_weight" ISNULL
|
jbe@532
|
2560 JOIN "direct_supporter_snapshot"
|
jbe@532
|
2561 ON "issue"."latest_snapshot_id" = "direct_supporter_snapshot"."snapshot_id"
|
jbe@532
|
2562 AND "initiative"."id" = "direct_supporter_snapshot"."initiative_id"
|
jbe@532
|
2563 AND "direct_interest_snapshot"."member_id" = "direct_supporter_snapshot"."member_id"
|
jbe@532
|
2564 AND (
|
jbe@532
|
2565 "direct_supporter_snapshot"."satisfied" = TRUE OR
|
jbe@532
|
2566 coalesce("initiative"."admitted", FALSE) = FALSE
|
jbe@532
|
2567 )
|
jbe@532
|
2568 GROUP BY
|
jbe@532
|
2569 "direct_interest_snapshot"."snapshot_id",
|
jbe@532
|
2570 "direct_interest_snapshot"."issue_id",
|
jbe@532
|
2571 "direct_interest_snapshot"."member_id",
|
jbe@532
|
2572 "direct_interest_snapshot"."weight";
|
jbe@532
|
2573
|
jbe@532
|
2574
|
jbe@532
|
2575 CREATE VIEW "remaining_harmonic_initiative_weight_summands" AS
|
jbe@532
|
2576 SELECT
|
jbe@532
|
2577 "initiative"."issue_id",
|
jbe@532
|
2578 "initiative"."id" AS "initiative_id",
|
jbe@532
|
2579 "initiative"."admitted",
|
jbe@532
|
2580 sum("remaining_harmonic_supporter_weight"."weight_num") AS "weight_num",
|
jbe@532
|
2581 "remaining_harmonic_supporter_weight"."weight_den"
|
jbe@532
|
2582 FROM "remaining_harmonic_supporter_weight"
|
jbe@532
|
2583 JOIN "initiative"
|
jbe@532
|
2584 ON "remaining_harmonic_supporter_weight"."issue_id" = "initiative"."issue_id"
|
jbe@532
|
2585 AND "initiative"."harmonic_weight" ISNULL
|
jbe@532
|
2586 JOIN "direct_supporter_snapshot"
|
jbe@532
|
2587 ON "remaining_harmonic_supporter_weight"."snapshot_id" = "direct_supporter_snapshot"."snapshot_id"
|
jbe@532
|
2588 AND "initiative"."id" = "direct_supporter_snapshot"."initiative_id"
|
jbe@532
|
2589 AND "remaining_harmonic_supporter_weight"."member_id" = "direct_supporter_snapshot"."member_id"
|
jbe@532
|
2590 AND (
|
jbe@532
|
2591 "direct_supporter_snapshot"."satisfied" = TRUE OR
|
jbe@532
|
2592 coalesce("initiative"."admitted", FALSE) = FALSE
|
jbe@532
|
2593 )
|
jbe@532
|
2594 GROUP BY
|
jbe@532
|
2595 "initiative"."issue_id",
|
jbe@532
|
2596 "initiative"."id",
|
jbe@532
|
2597 "initiative"."admitted",
|
jbe@532
|
2598 "remaining_harmonic_supporter_weight"."weight_den";
|
jbe@532
|
2599
|
jbe@532
|
2600
|
jbe@532
|
2601 DROP FUNCTION "create_population_snapshot"
|
jbe@532
|
2602 ( "issue_id_p" "issue"."id"%TYPE );
|
jbe@532
|
2603
|
jbe@532
|
2604
|
jbe@532
|
2605 DROP FUNCTION "weight_of_added_delegations_for_population_snapshot"
|
jbe@532
|
2606 ( "issue_id_p" "issue"."id"%TYPE,
|
jbe@532
|
2607 "member_id_p" "member"."id"%TYPE,
|
jbe@532
|
2608 "delegate_member_ids_p" "delegating_population_snapshot"."delegate_member_ids"%TYPE );
|
jbe@532
|
2609
|
jbe@532
|
2610
|
jbe@532
|
2611 DROP FUNCTION "weight_of_added_delegations_for_interest_snapshot"
|
jbe@532
|
2612 ( "issue_id_p" "issue"."id"%TYPE,
|
jbe@532
|
2613 "member_id_p" "member"."id"%TYPE,
|
jbe@532
|
2614 "delegate_member_ids_p" "delegating_interest_snapshot"."delegate_member_ids"%TYPE );
|
jbe@532
|
2615
|
jbe@532
|
2616
|
jbe@532
|
2617 CREATE FUNCTION "weight_of_added_delegations_for_snapshot"
|
jbe@532
|
2618 ( "snapshot_id_p" "snapshot"."id"%TYPE,
|
jbe@532
|
2619 "issue_id_p" "issue"."id"%TYPE,
|
jbe@532
|
2620 "member_id_p" "member"."id"%TYPE,
|
jbe@532
|
2621 "delegate_member_ids_p" "delegating_interest_snapshot"."delegate_member_ids"%TYPE )
|
jbe@532
|
2622 RETURNS "direct_interest_snapshot"."weight"%TYPE
|
jbe@532
|
2623 LANGUAGE 'plpgsql' VOLATILE AS $$
|
jbe@532
|
2624 DECLARE
|
jbe@532
|
2625 "issue_delegation_row" "issue_delegation"%ROWTYPE;
|
jbe@532
|
2626 "delegate_member_ids_v" "delegating_interest_snapshot"."delegate_member_ids"%TYPE;
|
jbe@532
|
2627 "weight_v" INT4;
|
jbe@532
|
2628 "sub_weight_v" INT4;
|
jbe@532
|
2629 BEGIN
|
jbe@532
|
2630 PERFORM "require_transaction_isolation"();
|
jbe@532
|
2631 "weight_v" := 0;
|
jbe@532
|
2632 FOR "issue_delegation_row" IN
|
jbe@532
|
2633 SELECT * FROM "issue_delegation"
|
jbe@532
|
2634 WHERE "trustee_id" = "member_id_p"
|
jbe@532
|
2635 AND "issue_id" = "issue_id_p"
|
jbe@532
|
2636 LOOP
|
jbe@532
|
2637 IF NOT EXISTS (
|
jbe@532
|
2638 SELECT NULL FROM "direct_interest_snapshot"
|
jbe@532
|
2639 WHERE "snapshot_id" = "snapshot_id_p"
|
jbe@532
|
2640 AND "issue_id" = "issue_id_p"
|
jbe@532
|
2641 AND "member_id" = "issue_delegation_row"."truster_id"
|
jbe@532
|
2642 ) AND NOT EXISTS (
|
jbe@532
|
2643 SELECT NULL FROM "delegating_interest_snapshot"
|
jbe@532
|
2644 WHERE "snapshot_id" = "snapshot_id_p"
|
jbe@532
|
2645 AND "issue_id" = "issue_id_p"
|
jbe@532
|
2646 AND "member_id" = "issue_delegation_row"."truster_id"
|
jbe@532
|
2647 ) THEN
|
jbe@532
|
2648 "delegate_member_ids_v" :=
|
jbe@532
|
2649 "member_id_p" || "delegate_member_ids_p";
|
jbe@532
|
2650 INSERT INTO "delegating_interest_snapshot" (
|
jbe@532
|
2651 "snapshot_id",
|
jbe@532
|
2652 "issue_id",
|
jbe@532
|
2653 "member_id",
|
jbe@532
|
2654 "scope",
|
jbe@532
|
2655 "delegate_member_ids"
|
jbe@532
|
2656 ) VALUES (
|
jbe@532
|
2657 "snapshot_id_p",
|
jbe@532
|
2658 "issue_id_p",
|
jbe@532
|
2659 "issue_delegation_row"."truster_id",
|
jbe@532
|
2660 "issue_delegation_row"."scope",
|
jbe@532
|
2661 "delegate_member_ids_v"
|
jbe@532
|
2662 );
|
jbe@532
|
2663 "sub_weight_v" := 1 +
|
jbe@532
|
2664 "weight_of_added_delegations_for_snapshot"(
|
jbe@532
|
2665 "snapshot_id_p",
|
jbe@532
|
2666 "issue_id_p",
|
jbe@532
|
2667 "issue_delegation_row"."truster_id",
|
jbe@532
|
2668 "delegate_member_ids_v"
|
jbe@532
|
2669 );
|
jbe@532
|
2670 UPDATE "delegating_interest_snapshot"
|
jbe@532
|
2671 SET "weight" = "sub_weight_v"
|
jbe@532
|
2672 WHERE "snapshot_id" = "snapshot_id_p"
|
jbe@532
|
2673 AND "issue_id" = "issue_id_p"
|
jbe@532
|
2674 AND "member_id" = "issue_delegation_row"."truster_id";
|
jbe@532
|
2675 "weight_v" := "weight_v" + "sub_weight_v";
|
jbe@532
|
2676 END IF;
|
jbe@532
|
2677 END LOOP;
|
jbe@532
|
2678 RETURN "weight_v";
|
jbe@532
|
2679 END;
|
jbe@532
|
2680 $$;
|
jbe@532
|
2681
|
jbe@532
|
2682 COMMENT ON FUNCTION "weight_of_added_delegations_for_snapshot"
|
jbe@532
|
2683 ( "snapshot"."id"%TYPE,
|
jbe@532
|
2684 "issue"."id"%TYPE,
|
jbe@532
|
2685 "member"."id"%TYPE,
|
jbe@532
|
2686 "delegating_interest_snapshot"."delegate_member_ids"%TYPE )
|
jbe@532
|
2687 IS 'Helper function for "fill_snapshot" function';
|
jbe@532
|
2688
|
jbe@532
|
2689
|
jbe@532
|
2690 DROP FUNCTION "create_interest_snapshot"
|
jbe@532
|
2691 ( "issue_id_p" "issue"."id"%TYPE );
|
jbe@532
|
2692
|
jbe@532
|
2693
|
jbe@532
|
2694 DROP FUNCTION "create_snapshot"
|
jbe@532
|
2695 ( "issue_id_p" "issue"."id"%TYPE );
|
jbe@532
|
2696
|
jbe@532
|
2697
|
jbe@532
|
2698 CREATE FUNCTION "take_snapshot"
|
jbe@532
|
2699 ( "issue_id_p" "issue"."id"%TYPE,
|
jbe@532
|
2700 "area_id_p" "area"."id"%TYPE = NULL )
|
jbe@532
|
2701 RETURNS "snapshot"."id"%TYPE
|
jbe@532
|
2702 LANGUAGE 'plpgsql' VOLATILE AS $$
|
jbe@532
|
2703 DECLARE
|
jbe@532
|
2704 "area_id_v" "area"."id"%TYPE;
|
jbe@532
|
2705 "unit_id_v" "unit"."id"%TYPE;
|
jbe@532
|
2706 "snapshot_id_v" "snapshot"."id"%TYPE;
|
jbe@532
|
2707 "issue_id_v" "issue"."id"%TYPE;
|
jbe@532
|
2708 "member_id_v" "member"."id"%TYPE;
|
jbe@532
|
2709 BEGIN
|
jbe@532
|
2710 IF "issue_id_p" NOTNULL AND "area_id_p" NOTNULL THEN
|
jbe@532
|
2711 RAISE EXCEPTION 'One of "issue_id_p" and "area_id_p" must be NULL';
|
jbe@532
|
2712 END IF;
|
jbe@532
|
2713 PERFORM "require_transaction_isolation"();
|
jbe@532
|
2714 IF "issue_id_p" ISNULL THEN
|
jbe@532
|
2715 "area_id_v" := "area_id_p";
|
jbe@532
|
2716 ELSE
|
jbe@532
|
2717 SELECT "area_id" INTO "area_id_v"
|
jbe@532
|
2718 FROM "issue" WHERE "id" = "issue_id_p";
|
jbe@532
|
2719 END IF;
|
jbe@532
|
2720 SELECT "unit_id" INTO "unit_id_v" FROM "area" WHERE "id" = "area_id_p";
|
jbe@532
|
2721 INSERT INTO "snapshot" ("area_id", "issue_id")
|
jbe@532
|
2722 VALUES ("area_id_v", "issue_id_p")
|
jbe@532
|
2723 RETURNING "id" INTO "snapshot_id_v";
|
jbe@532
|
2724 INSERT INTO "snapshot_population" ("snapshot_id", "member_id")
|
jbe@532
|
2725 SELECT "snapshot_id_v", "member_id"
|
jbe@532
|
2726 FROM "unit_member" WHERE "unit_id" = "unit_id_v";
|
jbe@532
|
2727 UPDATE "snapshot" SET
|
jbe@532
|
2728 "population" = (
|
jbe@532
|
2729 SELECT count(1) FROM "snapshot_population"
|
jbe@532
|
2730 WHERE "snapshot_id" = "snapshot_id_v"
|
jbe@532
|
2731 ) WHERE "id" = "snapshot_id_v";
|
jbe@532
|
2732 FOR "issue_id_v" IN
|
jbe@532
|
2733 SELECT "id" FROM "issue"
|
jbe@532
|
2734 WHERE CASE WHEN "issue_id_p" ISNULL THEN
|
jbe@532
|
2735 "area_id" = "area_id_p" AND
|
jbe@532
|
2736 "state" = 'admission'
|
jbe@532
|
2737 ELSE
|
jbe@532
|
2738 "id" = "issue_id_p"
|
jbe@532
|
2739 END
|
jbe@532
|
2740 LOOP
|
jbe@532
|
2741 INSERT INTO "snapshot_issue" ("snapshot_id", "issue_id")
|
jbe@532
|
2742 VALUES ("snapshot_id_v", "issue_id_v");
|
jbe@532
|
2743 INSERT INTO "direct_interest_snapshot"
|
jbe@532
|
2744 ("snapshot_id", "issue_id", "member_id")
|
jbe@532
|
2745 SELECT
|
jbe@532
|
2746 "snapshot_id_v" AS "snapshot_id",
|
jbe@532
|
2747 "issue_id_v" AS "issue_id",
|
jbe@532
|
2748 "member"."id" AS "member_id"
|
jbe@532
|
2749 FROM "issue"
|
jbe@532
|
2750 JOIN "area" ON "issue"."area_id" = "area"."id"
|
jbe@532
|
2751 JOIN "interest" ON "issue"."id" = "interest"."issue_id"
|
jbe@532
|
2752 JOIN "member" ON "interest"."member_id" = "member"."id"
|
jbe@556
|
2753 JOIN "privilege"
|
jbe@556
|
2754 ON "privilege"."unit_id" = "area"."unit_id"
|
jbe@556
|
2755 AND "privilege"."member_id" = "member"."id"
|
jbe@532
|
2756 WHERE "issue"."id" = "issue_id_v"
|
jbe@556
|
2757 AND "member"."active" AND "privilege"."voting_right";
|
jbe@532
|
2758 FOR "member_id_v" IN
|
jbe@532
|
2759 SELECT "member_id" FROM "direct_interest_snapshot"
|
jbe@532
|
2760 WHERE "snapshot_id" = "snapshot_id_v"
|
jbe@532
|
2761 AND "issue_id" = "issue_id_v"
|
jbe@532
|
2762 LOOP
|
jbe@532
|
2763 UPDATE "direct_interest_snapshot" SET
|
jbe@532
|
2764 "weight" = 1 +
|
jbe@532
|
2765 "weight_of_added_delegations_for_snapshot"(
|
jbe@532
|
2766 "snapshot_id_v",
|
jbe@532
|
2767 "issue_id_v",
|
jbe@532
|
2768 "member_id_v",
|
jbe@532
|
2769 '{}'
|
jbe@532
|
2770 )
|
jbe@532
|
2771 WHERE "snapshot_id" = "snapshot_id_v"
|
jbe@532
|
2772 AND "issue_id" = "issue_id_v"
|
jbe@532
|
2773 AND "member_id" = "member_id_v";
|
jbe@532
|
2774 END LOOP;
|
jbe@532
|
2775 INSERT INTO "direct_supporter_snapshot"
|
jbe@532
|
2776 ( "snapshot_id", "issue_id", "initiative_id", "member_id",
|
jbe@532
|
2777 "draft_id", "informed", "satisfied" )
|
jbe@532
|
2778 SELECT
|
jbe@532
|
2779 "snapshot_id_v" AS "snapshot_id",
|
jbe@532
|
2780 "issue_id_v" AS "issue_id",
|
jbe@532
|
2781 "initiative"."id" AS "initiative_id",
|
jbe@532
|
2782 "supporter"."member_id" AS "member_id",
|
jbe@532
|
2783 "supporter"."draft_id" AS "draft_id",
|
jbe@532
|
2784 "supporter"."draft_id" = "current_draft"."id" AS "informed",
|
jbe@532
|
2785 NOT EXISTS (
|
jbe@532
|
2786 SELECT NULL FROM "critical_opinion"
|
jbe@532
|
2787 WHERE "initiative_id" = "initiative"."id"
|
jbe@532
|
2788 AND "member_id" = "supporter"."member_id"
|
jbe@532
|
2789 ) AS "satisfied"
|
jbe@532
|
2790 FROM "initiative"
|
jbe@532
|
2791 JOIN "supporter"
|
jbe@532
|
2792 ON "supporter"."initiative_id" = "initiative"."id"
|
jbe@532
|
2793 JOIN "current_draft"
|
jbe@532
|
2794 ON "initiative"."id" = "current_draft"."initiative_id"
|
jbe@532
|
2795 JOIN "direct_interest_snapshot"
|
jbe@532
|
2796 ON "snapshot_id_v" = "direct_interest_snapshot"."snapshot_id"
|
jbe@532
|
2797 AND "supporter"."member_id" = "direct_interest_snapshot"."member_id"
|
jbe@532
|
2798 AND "initiative"."issue_id" = "direct_interest_snapshot"."issue_id"
|
jbe@532
|
2799 WHERE "initiative"."issue_id" = "issue_id_v";
|
jbe@532
|
2800 DELETE FROM "temporary_suggestion_counts";
|
jbe@532
|
2801 INSERT INTO "temporary_suggestion_counts"
|
jbe@532
|
2802 ( "id",
|
jbe@532
|
2803 "minus2_unfulfilled_count", "minus2_fulfilled_count",
|
jbe@532
|
2804 "minus1_unfulfilled_count", "minus1_fulfilled_count",
|
jbe@532
|
2805 "plus1_unfulfilled_count", "plus1_fulfilled_count",
|
jbe@532
|
2806 "plus2_unfulfilled_count", "plus2_fulfilled_count" )
|
jbe@532
|
2807 SELECT
|
jbe@532
|
2808 "suggestion"."id",
|
jbe@532
|
2809 ( SELECT coalesce(sum("di"."weight"), 0)
|
jbe@532
|
2810 FROM "opinion" JOIN "direct_interest_snapshot" AS "di"
|
jbe@532
|
2811 ON "di"."snapshot_id" = "snapshot_id_v"
|
jbe@532
|
2812 AND "di"."issue_id" = "issue_id_v"
|
jbe@532
|
2813 AND "di"."member_id" = "opinion"."member_id"
|
jbe@532
|
2814 WHERE "opinion"."suggestion_id" = "suggestion"."id"
|
jbe@532
|
2815 AND "opinion"."degree" = -2
|
jbe@532
|
2816 AND "opinion"."fulfilled" = FALSE
|
jbe@532
|
2817 ) AS "minus2_unfulfilled_count",
|
jbe@532
|
2818 ( SELECT coalesce(sum("di"."weight"), 0)
|
jbe@532
|
2819 FROM "opinion" JOIN "direct_interest_snapshot" AS "di"
|
jbe@532
|
2820 ON "di"."snapshot_id" = "snapshot_id_v"
|
jbe@532
|
2821 AND "di"."issue_id" = "issue_id_v"
|
jbe@532
|
2822 AND "di"."member_id" = "opinion"."member_id"
|
jbe@532
|
2823 WHERE "opinion"."suggestion_id" = "suggestion"."id"
|
jbe@532
|
2824 AND "opinion"."degree" = -2
|
jbe@532
|
2825 AND "opinion"."fulfilled" = TRUE
|
jbe@532
|
2826 ) AS "minus2_fulfilled_count",
|
jbe@532
|
2827 ( SELECT coalesce(sum("di"."weight"), 0)
|
jbe@532
|
2828 FROM "opinion" JOIN "direct_interest_snapshot" AS "di"
|
jbe@532
|
2829 ON "di"."snapshot_id" = "snapshot_id_v"
|
jbe@532
|
2830 AND "di"."issue_id" = "issue_id_v"
|
jbe@532
|
2831 AND "di"."member_id" = "opinion"."member_id"
|
jbe@532
|
2832 WHERE "opinion"."suggestion_id" = "suggestion"."id"
|
jbe@532
|
2833 AND "opinion"."degree" = -1
|
jbe@532
|
2834 AND "opinion"."fulfilled" = FALSE
|
jbe@532
|
2835 ) AS "minus1_unfulfilled_count",
|
jbe@532
|
2836 ( SELECT coalesce(sum("di"."weight"), 0)
|
jbe@532
|
2837 FROM "opinion" JOIN "direct_interest_snapshot" AS "di"
|
jbe@532
|
2838 ON "di"."snapshot_id" = "snapshot_id_v"
|
jbe@532
|
2839 AND "di"."issue_id" = "issue_id_v"
|
jbe@532
|
2840 AND "di"."member_id" = "opinion"."member_id"
|
jbe@532
|
2841 WHERE "opinion"."suggestion_id" = "suggestion"."id"
|
jbe@532
|
2842 AND "opinion"."degree" = -1
|
jbe@532
|
2843 AND "opinion"."fulfilled" = TRUE
|
jbe@532
|
2844 ) AS "minus1_fulfilled_count",
|
jbe@532
|
2845 ( SELECT coalesce(sum("di"."weight"), 0)
|
jbe@532
|
2846 FROM "opinion" JOIN "direct_interest_snapshot" AS "di"
|
jbe@532
|
2847 ON "di"."snapshot_id" = "snapshot_id_v"
|
jbe@532
|
2848 AND "di"."issue_id" = "issue_id_v"
|
jbe@532
|
2849 AND "di"."member_id" = "opinion"."member_id"
|
jbe@532
|
2850 WHERE "opinion"."suggestion_id" = "suggestion"."id"
|
jbe@532
|
2851 AND "opinion"."degree" = 1
|
jbe@532
|
2852 AND "opinion"."fulfilled" = FALSE
|
jbe@532
|
2853 ) AS "plus1_unfulfilled_count",
|
jbe@532
|
2854 ( SELECT coalesce(sum("di"."weight"), 0)
|
jbe@532
|
2855 FROM "opinion" JOIN "direct_interest_snapshot" AS "di"
|
jbe@532
|
2856 ON "di"."snapshot_id" = "snapshot_id_v"
|
jbe@532
|
2857 AND "di"."issue_id" = "issue_id_v"
|
jbe@532
|
2858 AND "di"."member_id" = "opinion"."member_id"
|
jbe@532
|
2859 WHERE "opinion"."suggestion_id" = "suggestion"."id"
|
jbe@532
|
2860 AND "opinion"."degree" = 1
|
jbe@532
|
2861 AND "opinion"."fulfilled" = TRUE
|
jbe@532
|
2862 ) AS "plus1_fulfilled_count",
|
jbe@532
|
2863 ( SELECT coalesce(sum("di"."weight"), 0)
|
jbe@532
|
2864 FROM "opinion" JOIN "direct_interest_snapshot" AS "di"
|
jbe@532
|
2865 ON "di"."snapshot_id" = "snapshot_id_v"
|
jbe@532
|
2866 AND "di"."issue_id" = "issue_id_v"
|
jbe@532
|
2867 AND "di"."member_id" = "opinion"."member_id"
|
jbe@532
|
2868 WHERE "opinion"."suggestion_id" = "suggestion"."id"
|
jbe@532
|
2869 AND "opinion"."degree" = 2
|
jbe@532
|
2870 AND "opinion"."fulfilled" = FALSE
|
jbe@532
|
2871 ) AS "plus2_unfulfilled_count",
|
jbe@532
|
2872 ( SELECT coalesce(sum("di"."weight"), 0)
|
jbe@532
|
2873 FROM "opinion" JOIN "direct_interest_snapshot" AS "di"
|
jbe@532
|
2874 ON "di"."snapshot_id" = "snapshot_id_v"
|
jbe@532
|
2875 AND "di"."issue_id" = "issue_id_v"
|
jbe@532
|
2876 AND "di"."member_id" = "opinion"."member_id"
|
jbe@532
|
2877 WHERE "opinion"."suggestion_id" = "suggestion"."id"
|
jbe@532
|
2878 AND "opinion"."degree" = 2
|
jbe@532
|
2879 AND "opinion"."fulfilled" = TRUE
|
jbe@532
|
2880 ) AS "plus2_fulfilled_count"
|
jbe@532
|
2881 FROM "suggestion" JOIN "initiative"
|
jbe@532
|
2882 ON "suggestion"."initiative_id" = "initiative"."id"
|
jbe@532
|
2883 WHERE "initiative"."issue_id" = "issue_id_v";
|
jbe@532
|
2884 END LOOP;
|
jbe@532
|
2885 RETURN "snapshot_id_v";
|
jbe@532
|
2886 END;
|
jbe@532
|
2887 $$;
|
jbe@532
|
2888
|
jbe@532
|
2889 COMMENT ON FUNCTION "take_snapshot"
|
jbe@532
|
2890 ( "issue"."id"%TYPE,
|
jbe@532
|
2891 "area"."id"%TYPE )
|
jbe@532
|
2892 IS 'This function creates a new interest/supporter snapshot of a particular issue, or, if the first argument is NULL, for all issues in ''admission'' phase of the area given as second argument. It must be executed with TRANSACTION ISOLATION LEVEL REPEATABLE READ. The snapshot must later be finished by calling "finish_snapshot" for every issue.';
|
jbe@532
|
2893
|
jbe@532
|
2894
|
jbe@532
|
2895 DROP FUNCTION "set_snapshot_event"
|
jbe@532
|
2896 ( "issue_id_p" "issue"."id"%TYPE,
|
jbe@532
|
2897 "event_p" "snapshot_event" );
|
jbe@532
|
2898
|
jbe@532
|
2899
|
jbe@532
|
2900 CREATE FUNCTION "finish_snapshot"
|
jbe@532
|
2901 ( "issue_id_p" "issue"."id"%TYPE )
|
jbe@532
|
2902 RETURNS VOID
|
jbe@532
|
2903 LANGUAGE 'plpgsql' VOLATILE AS $$
|
jbe@532
|
2904 DECLARE
|
jbe@532
|
2905 "snapshot_id_v" "snapshot"."id"%TYPE;
|
jbe@532
|
2906 BEGIN
|
jbe@532
|
2907 -- NOTE: function does not require snapshot isolation but we don't call
|
jbe@532
|
2908 -- "dont_require_snapshot_isolation" here because this function is
|
jbe@532
|
2909 -- also invoked by "check_issue"
|
jbe@532
|
2910 LOCK TABLE "snapshot" IN EXCLUSIVE MODE;
|
jbe@532
|
2911 SELECT "id" INTO "snapshot_id_v" FROM "snapshot"
|
jbe@532
|
2912 ORDER BY "id" DESC LIMIT 1;
|
jbe@532
|
2913 UPDATE "issue" SET
|
jbe@532
|
2914 "calculated" = "snapshot"."calculated",
|
jbe@532
|
2915 "latest_snapshot_id" = "snapshot_id_v",
|
jbe@532
|
2916 "population" = "snapshot"."population"
|
jbe@532
|
2917 FROM "snapshot"
|
jbe@532
|
2918 WHERE "issue"."id" = "issue_id_p"
|
jbe@532
|
2919 AND "snapshot"."id" = "snapshot_id_v";
|
jbe@532
|
2920 UPDATE "initiative" SET
|
jbe@532
|
2921 "supporter_count" = (
|
jbe@532
|
2922 SELECT coalesce(sum("di"."weight"), 0)
|
jbe@532
|
2923 FROM "direct_interest_snapshot" AS "di"
|
jbe@532
|
2924 JOIN "direct_supporter_snapshot" AS "ds"
|
jbe@532
|
2925 ON "di"."member_id" = "ds"."member_id"
|
jbe@532
|
2926 WHERE "di"."snapshot_id" = "snapshot_id_v"
|
jbe@532
|
2927 AND "di"."issue_id" = "issue_id_p"
|
jbe@532
|
2928 AND "ds"."snapshot_id" = "snapshot_id_v"
|
jbe@532
|
2929 AND "ds"."initiative_id" = "initiative"."id"
|
jbe@532
|
2930 ),
|
jbe@532
|
2931 "informed_supporter_count" = (
|
jbe@532
|
2932 SELECT coalesce(sum("di"."weight"), 0)
|
jbe@532
|
2933 FROM "direct_interest_snapshot" AS "di"
|
jbe@532
|
2934 JOIN "direct_supporter_snapshot" AS "ds"
|
jbe@532
|
2935 ON "di"."member_id" = "ds"."member_id"
|
jbe@532
|
2936 WHERE "di"."snapshot_id" = "snapshot_id_v"
|
jbe@532
|
2937 AND "di"."issue_id" = "issue_id_p"
|
jbe@532
|
2938 AND "ds"."snapshot_id" = "snapshot_id_v"
|
jbe@532
|
2939 AND "ds"."initiative_id" = "initiative"."id"
|
jbe@532
|
2940 AND "ds"."informed"
|
jbe@532
|
2941 ),
|
jbe@532
|
2942 "satisfied_supporter_count" = (
|
jbe@532
|
2943 SELECT coalesce(sum("di"."weight"), 0)
|
jbe@532
|
2944 FROM "direct_interest_snapshot" AS "di"
|
jbe@532
|
2945 JOIN "direct_supporter_snapshot" AS "ds"
|
jbe@532
|
2946 ON "di"."member_id" = "ds"."member_id"
|
jbe@532
|
2947 WHERE "di"."snapshot_id" = "snapshot_id_v"
|
jbe@532
|
2948 AND "di"."issue_id" = "issue_id_p"
|
jbe@532
|
2949 AND "ds"."snapshot_id" = "snapshot_id_v"
|
jbe@532
|
2950 AND "ds"."initiative_id" = "initiative"."id"
|
jbe@532
|
2951 AND "ds"."satisfied"
|
jbe@532
|
2952 ),
|
jbe@532
|
2953 "satisfied_informed_supporter_count" = (
|
jbe@532
|
2954 SELECT coalesce(sum("di"."weight"), 0)
|
jbe@532
|
2955 FROM "direct_interest_snapshot" AS "di"
|
jbe@532
|
2956 JOIN "direct_supporter_snapshot" AS "ds"
|
jbe@532
|
2957 ON "di"."member_id" = "ds"."member_id"
|
jbe@532
|
2958 WHERE "di"."snapshot_id" = "snapshot_id_v"
|
jbe@532
|
2959 AND "di"."issue_id" = "issue_id_p"
|
jbe@532
|
2960 AND "ds"."snapshot_id" = "snapshot_id_v"
|
jbe@532
|
2961 AND "ds"."initiative_id" = "initiative"."id"
|
jbe@532
|
2962 AND "ds"."informed"
|
jbe@532
|
2963 AND "ds"."satisfied"
|
jbe@532
|
2964 )
|
jbe@532
|
2965 WHERE "issue_id" = "issue_id_p";
|
jbe@532
|
2966 UPDATE "suggestion" SET
|
jbe@532
|
2967 "minus2_unfulfilled_count" = "temp"."minus2_unfulfilled_count",
|
jbe@532
|
2968 "minus2_fulfilled_count" = "temp"."minus2_fulfilled_count",
|
jbe@532
|
2969 "minus1_unfulfilled_count" = "temp"."minus1_unfulfilled_count",
|
jbe@532
|
2970 "minus1_fulfilled_count" = "temp"."minus1_fulfilled_count",
|
jbe@532
|
2971 "plus1_unfulfilled_count" = "temp"."plus1_unfulfilled_count",
|
jbe@532
|
2972 "plus1_fulfilled_count" = "temp"."plus1_fulfilled_count",
|
jbe@532
|
2973 "plus2_unfulfilled_count" = "temp"."plus2_unfulfilled_count",
|
jbe@532
|
2974 "plus2_fulfilled_count" = "temp"."plus2_fulfilled_count"
|
jbe@532
|
2975 FROM "temporary_suggestion_counts" AS "temp", "initiative"
|
jbe@532
|
2976 WHERE "temp"."id" = "suggestion"."id"
|
jbe@532
|
2977 AND "initiative"."issue_id" = "issue_id_p"
|
jbe@532
|
2978 AND "suggestion"."initiative_id" = "initiative"."id";
|
jbe@532
|
2979 DELETE FROM "temporary_suggestion_counts";
|
jbe@532
|
2980 RETURN;
|
jbe@532
|
2981 END;
|
jbe@532
|
2982 $$;
|
jbe@532
|
2983
|
jbe@532
|
2984 COMMENT ON FUNCTION "finish_snapshot"
|
jbe@532
|
2985 ( "issue"."id"%TYPE )
|
jbe@532
|
2986 IS 'After calling "take_snapshot", this function "finish_snapshot" needs to be called for every issue in the snapshot (separate function calls keep locking time minimal)';
|
jbe@532
|
2987
|
jbe@532
|
2988
|
jbe@532
|
2989 CREATE FUNCTION "issue_admission"
|
jbe@532
|
2990 ( "area_id_p" "area"."id"%TYPE )
|
jbe@532
|
2991 RETURNS BOOLEAN
|
jbe@532
|
2992 LANGUAGE 'plpgsql' VOLATILE AS $$
|
jbe@532
|
2993 DECLARE
|
jbe@532
|
2994 "issue_id_v" "issue"."id"%TYPE;
|
jbe@532
|
2995 BEGIN
|
jbe@532
|
2996 PERFORM "dont_require_transaction_isolation"();
|
jbe@532
|
2997 LOCK TABLE "snapshot" IN EXCLUSIVE MODE;
|
jbe@532
|
2998 UPDATE "area" SET "issue_quorum" = "view"."issue_quorum"
|
jbe@532
|
2999 FROM "area_quorum" AS "view"
|
jbe@532
|
3000 WHERE "area"."id" = "view"."area_id"
|
jbe@532
|
3001 AND "area"."id" = "area_id_p";
|
jbe@532
|
3002 SELECT "id" INTO "issue_id_v" FROM "issue_for_admission"
|
jbe@532
|
3003 WHERE "area_id" = "area_id_p";
|
jbe@532
|
3004 IF "issue_id_v" ISNULL THEN RETURN FALSE; END IF;
|
jbe@532
|
3005 UPDATE "issue" SET
|
jbe@532
|
3006 "admission_snapshot_id" = "latest_snapshot_id",
|
jbe@532
|
3007 "state" = 'discussion',
|
jbe@532
|
3008 "accepted" = now(),
|
jbe@532
|
3009 "phase_finished" = NULL
|
jbe@532
|
3010 WHERE "id" = "issue_id_v";
|
jbe@532
|
3011 RETURN TRUE;
|
jbe@532
|
3012 END;
|
jbe@532
|
3013 $$;
|
jbe@532
|
3014
|
jbe@532
|
3015 COMMENT ON FUNCTION "issue_admission"
|
jbe@532
|
3016 ( "area"."id"%TYPE )
|
jbe@532
|
3017 IS 'Checks if an issue in the area can be admitted for further discussion; returns TRUE on success in which case the function must be called again until it returns FALSE';
|
jbe@532
|
3018
|
jbe@532
|
3019
|
jbe@532
|
3020 CREATE OR REPLACE FUNCTION "check_issue"
|
jbe@532
|
3021 ( "issue_id_p" "issue"."id"%TYPE,
|
jbe@532
|
3022 "persist" "check_issue_persistence" )
|
jbe@532
|
3023 RETURNS "check_issue_persistence"
|
jbe@532
|
3024 LANGUAGE 'plpgsql' VOLATILE AS $$
|
jbe@532
|
3025 DECLARE
|
jbe@532
|
3026 "issue_row" "issue"%ROWTYPE;
|
jbe@532
|
3027 "last_calculated_v" "snapshot"."calculated"%TYPE;
|
jbe@532
|
3028 "policy_row" "policy"%ROWTYPE;
|
jbe@532
|
3029 "initiative_row" "initiative"%ROWTYPE;
|
jbe@532
|
3030 "state_v" "issue_state";
|
jbe@532
|
3031 BEGIN
|
jbe@532
|
3032 PERFORM "require_transaction_isolation"();
|
jbe@532
|
3033 IF "persist" ISNULL THEN
|
jbe@532
|
3034 SELECT * INTO "issue_row" FROM "issue" WHERE "id" = "issue_id_p"
|
jbe@532
|
3035 FOR UPDATE;
|
jbe@532
|
3036 SELECT "calculated" INTO "last_calculated_v"
|
jbe@532
|
3037 FROM "snapshot" JOIN "snapshot_issue"
|
jbe@532
|
3038 ON "snapshot"."id" = "snapshot_issue"."snapshot_id"
|
jbe@532
|
3039 WHERE "snapshot_issue"."issue_id" = "issue_id_p";
|
jbe@532
|
3040 IF "issue_row"."closed" NOTNULL THEN
|
jbe@532
|
3041 RETURN NULL;
|
jbe@532
|
3042 END IF;
|
jbe@532
|
3043 "persist"."state" := "issue_row"."state";
|
jbe@532
|
3044 IF
|
jbe@532
|
3045 ( "issue_row"."state" = 'admission' AND "last_calculated_v" >=
|
jbe@532
|
3046 "issue_row"."created" + "issue_row"."max_admission_time" ) OR
|
jbe@532
|
3047 ( "issue_row"."state" = 'discussion' AND now() >=
|
jbe@532
|
3048 "issue_row"."accepted" + "issue_row"."discussion_time" ) OR
|
jbe@532
|
3049 ( "issue_row"."state" = 'verification' AND now() >=
|
jbe@532
|
3050 "issue_row"."half_frozen" + "issue_row"."verification_time" ) OR
|
jbe@532
|
3051 ( "issue_row"."state" = 'voting' AND now() >=
|
jbe@532
|
3052 "issue_row"."fully_frozen" + "issue_row"."voting_time" )
|
jbe@532
|
3053 THEN
|
jbe@532
|
3054 "persist"."phase_finished" := TRUE;
|
jbe@532
|
3055 ELSE
|
jbe@532
|
3056 "persist"."phase_finished" := FALSE;
|
jbe@532
|
3057 END IF;
|
jbe@532
|
3058 IF
|
jbe@532
|
3059 NOT EXISTS (
|
jbe@532
|
3060 -- all initiatives are revoked
|
jbe@532
|
3061 SELECT NULL FROM "initiative"
|
jbe@532
|
3062 WHERE "issue_id" = "issue_id_p" AND "revoked" ISNULL
|
jbe@532
|
3063 ) AND (
|
jbe@532
|
3064 -- and issue has not been accepted yet
|
jbe@532
|
3065 "persist"."state" = 'admission' OR
|
jbe@532
|
3066 -- or verification time has elapsed
|
jbe@532
|
3067 ( "persist"."state" = 'verification' AND
|
jbe@532
|
3068 "persist"."phase_finished" ) OR
|
jbe@532
|
3069 -- or no initiatives have been revoked lately
|
jbe@532
|
3070 NOT EXISTS (
|
jbe@532
|
3071 SELECT NULL FROM "initiative"
|
jbe@532
|
3072 WHERE "issue_id" = "issue_id_p"
|
jbe@532
|
3073 AND now() < "revoked" + "issue_row"."verification_time"
|
jbe@532
|
3074 )
|
jbe@532
|
3075 )
|
jbe@532
|
3076 THEN
|
jbe@532
|
3077 "persist"."issue_revoked" := TRUE;
|
jbe@532
|
3078 ELSE
|
jbe@532
|
3079 "persist"."issue_revoked" := FALSE;
|
jbe@532
|
3080 END IF;
|
jbe@532
|
3081 IF "persist"."phase_finished" OR "persist"."issue_revoked" THEN
|
jbe@532
|
3082 UPDATE "issue" SET "phase_finished" = now()
|
jbe@532
|
3083 WHERE "id" = "issue_row"."id";
|
jbe@532
|
3084 RETURN "persist";
|
jbe@532
|
3085 ELSIF
|
jbe@532
|
3086 "persist"."state" IN ('admission', 'discussion', 'verification')
|
jbe@532
|
3087 THEN
|
jbe@532
|
3088 RETURN "persist";
|
jbe@532
|
3089 ELSE
|
jbe@532
|
3090 RETURN NULL;
|
jbe@532
|
3091 END IF;
|
jbe@532
|
3092 END IF;
|
jbe@532
|
3093 IF
|
jbe@532
|
3094 "persist"."state" IN ('admission', 'discussion', 'verification') AND
|
jbe@532
|
3095 coalesce("persist"."snapshot_created", FALSE) = FALSE
|
jbe@532
|
3096 THEN
|
jbe@532
|
3097 IF "persist"."state" != 'admission' THEN
|
jbe@532
|
3098 PERFORM "take_snapshot"("issue_id_p");
|
jbe@532
|
3099 PERFORM "finish_snapshot"("issue_id_p");
|
jbe@532
|
3100 END IF;
|
jbe@532
|
3101 "persist"."snapshot_created" = TRUE;
|
jbe@532
|
3102 IF "persist"."phase_finished" THEN
|
jbe@532
|
3103 IF "persist"."state" = 'admission' THEN
|
jbe@532
|
3104 UPDATE "issue" SET "admission_snapshot_id" = "latest_snapshot_id";
|
jbe@532
|
3105 ELSIF "persist"."state" = 'discussion' THEN
|
jbe@532
|
3106 UPDATE "issue" SET "half_freeze_snapshot_id" = "latest_snapshot_id";
|
jbe@532
|
3107 ELSIF "persist"."state" = 'verification' THEN
|
jbe@532
|
3108 UPDATE "issue" SET "full_freeze_snapshot_id" = "latest_snapshot_id";
|
jbe@532
|
3109 SELECT * INTO "issue_row" FROM "issue" WHERE "id" = "issue_id_p";
|
jbe@532
|
3110 SELECT * INTO "policy_row" FROM "policy"
|
jbe@532
|
3111 WHERE "id" = "issue_row"."policy_id";
|
jbe@532
|
3112 FOR "initiative_row" IN
|
jbe@532
|
3113 SELECT * FROM "initiative"
|
jbe@532
|
3114 WHERE "issue_id" = "issue_id_p" AND "revoked" ISNULL
|
jbe@532
|
3115 FOR UPDATE
|
jbe@532
|
3116 LOOP
|
jbe@532
|
3117 IF
|
jbe@532
|
3118 "initiative_row"."polling" OR (
|
jbe@532
|
3119 "initiative_row"."satisfied_supporter_count" >
|
jbe@532
|
3120 "policy_row"."initiative_quorum" AND
|
jbe@532
|
3121 "initiative_row"."satisfied_supporter_count" *
|
jbe@532
|
3122 "policy_row"."initiative_quorum_den" >=
|
jbe@532
|
3123 "issue_row"."population" * "policy_row"."initiative_quorum_num"
|
jbe@532
|
3124 )
|
jbe@532
|
3125 THEN
|
jbe@532
|
3126 UPDATE "initiative" SET "admitted" = TRUE
|
jbe@532
|
3127 WHERE "id" = "initiative_row"."id";
|
jbe@532
|
3128 ELSE
|
jbe@532
|
3129 UPDATE "initiative" SET "admitted" = FALSE
|
jbe@532
|
3130 WHERE "id" = "initiative_row"."id";
|
jbe@532
|
3131 END IF;
|
jbe@532
|
3132 END LOOP;
|
jbe@532
|
3133 END IF;
|
jbe@532
|
3134 END IF;
|
jbe@532
|
3135 RETURN "persist";
|
jbe@532
|
3136 END IF;
|
jbe@532
|
3137 IF
|
jbe@532
|
3138 "persist"."state" IN ('admission', 'discussion', 'verification') AND
|
jbe@532
|
3139 coalesce("persist"."harmonic_weights_set", FALSE) = FALSE
|
jbe@532
|
3140 THEN
|
jbe@532
|
3141 PERFORM "set_harmonic_initiative_weights"("issue_id_p");
|
jbe@532
|
3142 "persist"."harmonic_weights_set" = TRUE;
|
jbe@532
|
3143 IF
|
jbe@532
|
3144 "persist"."phase_finished" OR
|
jbe@532
|
3145 "persist"."issue_revoked" OR
|
jbe@532
|
3146 "persist"."state" = 'admission'
|
jbe@532
|
3147 THEN
|
jbe@532
|
3148 RETURN "persist";
|
jbe@532
|
3149 ELSE
|
jbe@532
|
3150 RETURN NULL;
|
jbe@532
|
3151 END IF;
|
jbe@532
|
3152 END IF;
|
jbe@532
|
3153 IF "persist"."issue_revoked" THEN
|
jbe@532
|
3154 IF "persist"."state" = 'admission' THEN
|
jbe@532
|
3155 "state_v" := 'canceled_revoked_before_accepted';
|
jbe@532
|
3156 ELSIF "persist"."state" = 'discussion' THEN
|
jbe@532
|
3157 "state_v" := 'canceled_after_revocation_during_discussion';
|
jbe@532
|
3158 ELSIF "persist"."state" = 'verification' THEN
|
jbe@532
|
3159 "state_v" := 'canceled_after_revocation_during_verification';
|
jbe@532
|
3160 END IF;
|
jbe@532
|
3161 UPDATE "issue" SET
|
jbe@532
|
3162 "state" = "state_v",
|
jbe@532
|
3163 "closed" = "phase_finished",
|
jbe@532
|
3164 "phase_finished" = NULL
|
jbe@532
|
3165 WHERE "id" = "issue_id_p";
|
jbe@532
|
3166 RETURN NULL;
|
jbe@532
|
3167 END IF;
|
jbe@532
|
3168 IF "persist"."state" = 'admission' THEN
|
jbe@532
|
3169 SELECT * INTO "issue_row" FROM "issue" WHERE "id" = "issue_id_p"
|
jbe@532
|
3170 FOR UPDATE;
|
jbe@532
|
3171 IF "issue_row"."phase_finished" NOTNULL THEN
|
jbe@532
|
3172 UPDATE "issue" SET
|
jbe@532
|
3173 "state" = 'canceled_issue_not_accepted',
|
jbe@532
|
3174 "closed" = "phase_finished",
|
jbe@532
|
3175 "phase_finished" = NULL
|
jbe@532
|
3176 WHERE "id" = "issue_id_p";
|
jbe@532
|
3177 END IF;
|
jbe@532
|
3178 RETURN NULL;
|
jbe@532
|
3179 END IF;
|
jbe@532
|
3180 IF "persist"."phase_finished" THEN
|
jbe@532
|
3181 IF "persist"."state" = 'discussion' THEN
|
jbe@532
|
3182 UPDATE "issue" SET
|
jbe@532
|
3183 "state" = 'verification',
|
jbe@532
|
3184 "half_frozen" = "phase_finished",
|
jbe@532
|
3185 "phase_finished" = NULL
|
jbe@532
|
3186 WHERE "id" = "issue_id_p";
|
jbe@532
|
3187 RETURN NULL;
|
jbe@532
|
3188 END IF;
|
jbe@532
|
3189 IF "persist"."state" = 'verification' THEN
|
jbe@532
|
3190 SELECT * INTO "issue_row" FROM "issue" WHERE "id" = "issue_id_p"
|
jbe@532
|
3191 FOR UPDATE;
|
jbe@532
|
3192 SELECT * INTO "policy_row" FROM "policy"
|
jbe@532
|
3193 WHERE "id" = "issue_row"."policy_id";
|
jbe@532
|
3194 IF EXISTS (
|
jbe@532
|
3195 SELECT NULL FROM "initiative"
|
jbe@532
|
3196 WHERE "issue_id" = "issue_id_p" AND "admitted" = TRUE
|
jbe@532
|
3197 ) THEN
|
jbe@532
|
3198 UPDATE "issue" SET
|
jbe@532
|
3199 "state" = 'voting',
|
jbe@532
|
3200 "fully_frozen" = "phase_finished",
|
jbe@532
|
3201 "phase_finished" = NULL
|
jbe@532
|
3202 WHERE "id" = "issue_id_p";
|
jbe@532
|
3203 ELSE
|
jbe@532
|
3204 UPDATE "issue" SET
|
jbe@532
|
3205 "state" = 'canceled_no_initiative_admitted',
|
jbe@532
|
3206 "fully_frozen" = "phase_finished",
|
jbe@532
|
3207 "closed" = "phase_finished",
|
jbe@532
|
3208 "phase_finished" = NULL
|
jbe@532
|
3209 WHERE "id" = "issue_id_p";
|
jbe@532
|
3210 -- NOTE: The following DELETE statements have effect only when
|
jbe@532
|
3211 -- issue state has been manipulated
|
jbe@532
|
3212 DELETE FROM "direct_voter" WHERE "issue_id" = "issue_id_p";
|
jbe@532
|
3213 DELETE FROM "delegating_voter" WHERE "issue_id" = "issue_id_p";
|
jbe@532
|
3214 DELETE FROM "battle" WHERE "issue_id" = "issue_id_p";
|
jbe@532
|
3215 END IF;
|
jbe@532
|
3216 RETURN NULL;
|
jbe@532
|
3217 END IF;
|
jbe@532
|
3218 IF "persist"."state" = 'voting' THEN
|
jbe@532
|
3219 IF coalesce("persist"."closed_voting", FALSE) = FALSE THEN
|
jbe@532
|
3220 PERFORM "close_voting"("issue_id_p");
|
jbe@532
|
3221 "persist"."closed_voting" = TRUE;
|
jbe@532
|
3222 RETURN "persist";
|
jbe@532
|
3223 END IF;
|
jbe@532
|
3224 PERFORM "calculate_ranks"("issue_id_p");
|
jbe@532
|
3225 RETURN NULL;
|
jbe@532
|
3226 END IF;
|
jbe@532
|
3227 END IF;
|
jbe@532
|
3228 RAISE WARNING 'should not happen';
|
jbe@532
|
3229 RETURN NULL;
|
jbe@532
|
3230 END;
|
jbe@532
|
3231 $$;
|
jbe@532
|
3232
|
jbe@532
|
3233
|
jbe@532
|
3234 CREATE OR REPLACE FUNCTION "check_everything"()
|
jbe@532
|
3235 RETURNS VOID
|
jbe@532
|
3236 LANGUAGE 'plpgsql' VOLATILE AS $$
|
jbe@532
|
3237 DECLARE
|
jbe@532
|
3238 "area_id_v" "area"."id"%TYPE;
|
jbe@532
|
3239 "snapshot_id_v" "snapshot"."id"%TYPE;
|
jbe@532
|
3240 "issue_id_v" "issue"."id"%TYPE;
|
jbe@532
|
3241 "persist_v" "check_issue_persistence";
|
jbe@532
|
3242 BEGIN
|
jbe@532
|
3243 RAISE WARNING 'Function "check_everything" should only be used for development and debugging purposes';
|
jbe@532
|
3244 DELETE FROM "expired_session";
|
jbe@532
|
3245 DELETE FROM "expired_token";
|
jbe@532
|
3246 DELETE FROM "expired_snapshot";
|
jbe@532
|
3247 PERFORM "check_activity"();
|
jbe@532
|
3248 PERFORM "calculate_member_counts"();
|
jbe@532
|
3249 FOR "area_id_v" IN SELECT "id" FROM "area_with_unaccepted_issues" LOOP
|
jbe@532
|
3250 SELECT "take_snapshot"(NULL, "area_id_v") INTO "snapshot_id_v";
|
jbe@532
|
3251 PERFORM "finish_snapshot"("issue_id") FROM "snapshot_issue"
|
jbe@532
|
3252 WHERE "snapshot_id" = "snapshot_id_v";
|
jbe@532
|
3253 LOOP
|
jbe@532
|
3254 EXIT WHEN "issue_admission"("area_id_v") = FALSE;
|
jbe@532
|
3255 END LOOP;
|
jbe@532
|
3256 END LOOP;
|
jbe@532
|
3257 FOR "issue_id_v" IN SELECT "id" FROM "open_issue" LOOP
|
jbe@532
|
3258 "persist_v" := NULL;
|
jbe@532
|
3259 LOOP
|
jbe@532
|
3260 "persist_v" := "check_issue"("issue_id_v", "persist_v");
|
jbe@532
|
3261 EXIT WHEN "persist_v" ISNULL;
|
jbe@532
|
3262 END LOOP;
|
jbe@532
|
3263 END LOOP;
|
jbe@532
|
3264 RETURN;
|
jbe@532
|
3265 END;
|
jbe@532
|
3266 $$;
|
jbe@532
|
3267
|
jbe@532
|
3268 COMMENT ON FUNCTION "check_everything"() IS 'Amongst other regular tasks, this function performs "check_issue" for every open issue. Use this function only for development and debugging purposes, as you may run into locking and/or serialization problems in productive environments. For production, use lf_update binary instead';
|
jbe@532
|
3269
|
jbe@532
|
3270
|
jbe@532
|
3271 CREATE OR REPLACE FUNCTION "clean_issue"("issue_id_p" "issue"."id"%TYPE)
|
jbe@532
|
3272 RETURNS VOID
|
jbe@532
|
3273 LANGUAGE 'plpgsql' VOLATILE AS $$
|
jbe@532
|
3274 BEGIN
|
jbe@532
|
3275 IF EXISTS (
|
jbe@532
|
3276 SELECT NULL FROM "issue" WHERE "id" = "issue_id_p" AND "cleaned" ISNULL
|
jbe@532
|
3277 ) THEN
|
jbe@532
|
3278 -- override protection triggers:
|
jbe@532
|
3279 INSERT INTO "temporary_transaction_data" ("key", "value")
|
jbe@532
|
3280 VALUES ('override_protection_triggers', TRUE::TEXT);
|
jbe@532
|
3281 -- clean data:
|
jbe@532
|
3282 DELETE FROM "delegating_voter"
|
jbe@532
|
3283 WHERE "issue_id" = "issue_id_p";
|
jbe@532
|
3284 DELETE FROM "direct_voter"
|
jbe@532
|
3285 WHERE "issue_id" = "issue_id_p";
|
jbe@532
|
3286 DELETE FROM "delegating_interest_snapshot"
|
jbe@532
|
3287 WHERE "issue_id" = "issue_id_p";
|
jbe@532
|
3288 DELETE FROM "direct_interest_snapshot"
|
jbe@532
|
3289 WHERE "issue_id" = "issue_id_p";
|
jbe@532
|
3290 DELETE FROM "non_voter"
|
jbe@532
|
3291 WHERE "issue_id" = "issue_id_p";
|
jbe@532
|
3292 DELETE FROM "delegation"
|
jbe@532
|
3293 WHERE "issue_id" = "issue_id_p";
|
jbe@532
|
3294 DELETE FROM "supporter"
|
jbe@532
|
3295 USING "initiative" -- NOTE: due to missing index on issue_id
|
jbe@532
|
3296 WHERE "initiative"."issue_id" = "issue_id_p"
|
jbe@532
|
3297 AND "supporter"."initiative_id" = "initiative_id";
|
jbe@532
|
3298 -- mark issue as cleaned:
|
jbe@532
|
3299 UPDATE "issue" SET "cleaned" = now() WHERE "id" = "issue_id_p";
|
jbe@532
|
3300 -- finish overriding protection triggers (avoids garbage):
|
jbe@532
|
3301 DELETE FROM "temporary_transaction_data"
|
jbe@532
|
3302 WHERE "key" = 'override_protection_triggers';
|
jbe@532
|
3303 END IF;
|
jbe@532
|
3304 RETURN;
|
jbe@532
|
3305 END;
|
jbe@532
|
3306 $$;
|
jbe@532
|
3307
|
jbe@532
|
3308
|
jbe@532
|
3309 CREATE OR REPLACE FUNCTION "delete_member"("member_id_p" "member"."id"%TYPE)
|
jbe@532
|
3310 RETURNS VOID
|
jbe@532
|
3311 LANGUAGE 'plpgsql' VOLATILE AS $$
|
jbe@532
|
3312 BEGIN
|
jbe@532
|
3313 UPDATE "member" SET
|
jbe@532
|
3314 "last_login" = NULL,
|
jbe@532
|
3315 "last_delegation_check" = NULL,
|
jbe@532
|
3316 "login" = NULL,
|
jbe@532
|
3317 "password" = NULL,
|
jbe@532
|
3318 "authority" = NULL,
|
jbe@532
|
3319 "authority_uid" = NULL,
|
jbe@532
|
3320 "authority_login" = NULL,
|
jbe@552
|
3321 "deleted" = coalesce("deleted", now()),
|
jbe@532
|
3322 "locked" = TRUE,
|
jbe@532
|
3323 "active" = FALSE,
|
jbe@532
|
3324 "notify_email" = NULL,
|
jbe@532
|
3325 "notify_email_unconfirmed" = NULL,
|
jbe@532
|
3326 "notify_email_secret" = NULL,
|
jbe@532
|
3327 "notify_email_secret_expiry" = NULL,
|
jbe@532
|
3328 "notify_email_lock_expiry" = NULL,
|
jbe@532
|
3329 "disable_notifications" = TRUE,
|
jbe@532
|
3330 "notification_counter" = DEFAULT,
|
jbe@532
|
3331 "notification_sample_size" = 0,
|
jbe@532
|
3332 "notification_dow" = NULL,
|
jbe@532
|
3333 "notification_hour" = NULL,
|
jbe@543
|
3334 "notification_sent" = NULL,
|
jbe@532
|
3335 "login_recovery_expiry" = NULL,
|
jbe@532
|
3336 "password_reset_secret" = NULL,
|
jbe@532
|
3337 "password_reset_secret_expiry" = NULL,
|
jbe@532
|
3338 "location" = NULL
|
jbe@532
|
3339 WHERE "id" = "member_id_p";
|
jbe@532
|
3340 -- "text_search_data" is updated by triggers
|
jbe@544
|
3341 DELETE FROM "member_settings" WHERE "member_id" = "member_id_p";
|
jbe@543
|
3342 DELETE FROM "member_profile" WHERE "member_id" = "member_id_p";
|
jbe@543
|
3343 DELETE FROM "rendered_member_statement" WHERE "member_id" = "member_id_p";
|
jbe@532
|
3344 DELETE FROM "member_image" WHERE "member_id" = "member_id_p";
|
jbe@532
|
3345 DELETE FROM "contact" WHERE "member_id" = "member_id_p";
|
jbe@532
|
3346 DELETE FROM "ignored_member" WHERE "member_id" = "member_id_p";
|
jbe@532
|
3347 DELETE FROM "session" WHERE "member_id" = "member_id_p";
|
jbe@543
|
3348 DELETE FROM "member_application" WHERE "member_id" = "member_id_p";
|
jbe@543
|
3349 DELETE FROM "token" WHERE "member_id" = "member_id_p";
|
jbe@543
|
3350 DELETE FROM "subscription" WHERE "member_id" = "member_id_p";
|
jbe@543
|
3351 DELETE FROM "ignored_area" WHERE "member_id" = "member_id_p";
|
jbe@532
|
3352 DELETE FROM "ignored_initiative" WHERE "member_id" = "member_id_p";
|
jbe@532
|
3353 DELETE FROM "delegation" WHERE "truster_id" = "member_id_p";
|
jbe@532
|
3354 DELETE FROM "non_voter" WHERE "member_id" = "member_id_p";
|
jbe@532
|
3355 DELETE FROM "direct_voter" USING "issue"
|
jbe@532
|
3356 WHERE "direct_voter"."issue_id" = "issue"."id"
|
jbe@532
|
3357 AND "issue"."closed" ISNULL
|
jbe@532
|
3358 AND "member_id" = "member_id_p";
|
jbe@543
|
3359 DELETE FROM "notification_initiative_sent" WHERE "member_id" = "member_id_p";
|
jbe@532
|
3360 RETURN;
|
jbe@532
|
3361 END;
|
jbe@532
|
3362 $$;
|
jbe@532
|
3363
|
jbe@532
|
3364
|
jbe@532
|
3365 CREATE OR REPLACE FUNCTION "delete_private_data"()
|
jbe@532
|
3366 RETURNS VOID
|
jbe@532
|
3367 LANGUAGE 'plpgsql' VOLATILE AS $$
|
jbe@532
|
3368 BEGIN
|
jbe@532
|
3369 DELETE FROM "temporary_transaction_data";
|
jbe@543
|
3370 DELETE FROM "temporary_suggestion_counts";
|
jbe@532
|
3371 DELETE FROM "member" WHERE "activated" ISNULL;
|
jbe@532
|
3372 UPDATE "member" SET
|
jbe@532
|
3373 "invite_code" = NULL,
|
jbe@532
|
3374 "invite_code_expiry" = NULL,
|
jbe@532
|
3375 "admin_comment" = NULL,
|
jbe@532
|
3376 "last_login" = NULL,
|
jbe@532
|
3377 "last_delegation_check" = NULL,
|
jbe@532
|
3378 "login" = NULL,
|
jbe@532
|
3379 "password" = NULL,
|
jbe@532
|
3380 "authority" = NULL,
|
jbe@532
|
3381 "authority_uid" = NULL,
|
jbe@532
|
3382 "authority_login" = NULL,
|
jbe@532
|
3383 "lang" = NULL,
|
jbe@532
|
3384 "notify_email" = NULL,
|
jbe@532
|
3385 "notify_email_unconfirmed" = NULL,
|
jbe@532
|
3386 "notify_email_secret" = NULL,
|
jbe@532
|
3387 "notify_email_secret_expiry" = NULL,
|
jbe@532
|
3388 "notify_email_lock_expiry" = NULL,
|
jbe@532
|
3389 "disable_notifications" = TRUE,
|
jbe@532
|
3390 "notification_counter" = DEFAULT,
|
jbe@532
|
3391 "notification_sample_size" = 0,
|
jbe@532
|
3392 "notification_dow" = NULL,
|
jbe@532
|
3393 "notification_hour" = NULL,
|
jbe@543
|
3394 "notification_sent" = NULL,
|
jbe@532
|
3395 "login_recovery_expiry" = NULL,
|
jbe@532
|
3396 "password_reset_secret" = NULL,
|
jbe@532
|
3397 "password_reset_secret_expiry" = NULL,
|
jbe@532
|
3398 "location" = NULL;
|
jbe@532
|
3399 -- "text_search_data" is updated by triggers
|
jbe@557
|
3400 DELETE FROM "verification";
|
jbe@544
|
3401 DELETE FROM "member_settings";
|
jbe@544
|
3402 DELETE FROM "member_useterms";
|
jbe@543
|
3403 DELETE FROM "member_profile";
|
jbe@543
|
3404 DELETE FROM "rendered_member_statement";
|
jbe@532
|
3405 DELETE FROM "member_image";
|
jbe@532
|
3406 DELETE FROM "contact";
|
jbe@532
|
3407 DELETE FROM "ignored_member";
|
jbe@532
|
3408 DELETE FROM "session";
|
jbe@543
|
3409 DELETE FROM "system_application";
|
jbe@543
|
3410 DELETE FROM "system_application_redirect_uri";
|
jbe@543
|
3411 DELETE FROM "dynamic_application_scope";
|
jbe@543
|
3412 DELETE FROM "member_application";
|
jbe@543
|
3413 DELETE FROM "token";
|
jbe@543
|
3414 DELETE FROM "subscription";
|
jbe@543
|
3415 DELETE FROM "ignored_area";
|
jbe@532
|
3416 DELETE FROM "ignored_initiative";
|
jbe@532
|
3417 DELETE FROM "non_voter";
|
jbe@532
|
3418 DELETE FROM "direct_voter" USING "issue"
|
jbe@532
|
3419 WHERE "direct_voter"."issue_id" = "issue"."id"
|
jbe@532
|
3420 AND "issue"."closed" ISNULL;
|
jbe@543
|
3421 DELETE FROM "event_processed";
|
jbe@543
|
3422 DELETE FROM "notification_initiative_sent";
|
jbe@543
|
3423 DELETE FROM "newsletter";
|
jbe@532
|
3424 RETURN;
|
jbe@532
|
3425 END;
|
jbe@532
|
3426 $$;
|
jbe@532
|
3427
|
jbe@532
|
3428
|
jbe@532
|
3429 CREATE TEMPORARY TABLE "old_snapshot" AS
|
jbe@532
|
3430 SELECT "ordered".*, row_number() OVER () AS "snapshot_id"
|
jbe@532
|
3431 FROM (
|
jbe@532
|
3432 SELECT * FROM (
|
jbe@532
|
3433 SELECT
|
jbe@532
|
3434 "id" AS "issue_id",
|
jbe@532
|
3435 'end_of_admission'::"snapshot_event" AS "event",
|
jbe@532
|
3436 "accepted" AS "calculated"
|
jbe@532
|
3437 FROM "issue" WHERE "accepted" NOTNULL
|
jbe@532
|
3438 UNION ALL
|
jbe@532
|
3439 SELECT
|
jbe@532
|
3440 "id" AS "issue_id",
|
jbe@532
|
3441 'half_freeze'::"snapshot_event" AS "event",
|
jbe@532
|
3442 "half_frozen" AS "calculated"
|
jbe@532
|
3443 FROM "issue" WHERE "half_frozen" NOTNULL
|
jbe@532
|
3444 UNION ALL
|
jbe@532
|
3445 SELECT
|
jbe@532
|
3446 "id" AS "issue_id",
|
jbe@532
|
3447 'full_freeze'::"snapshot_event" AS "event",
|
jbe@532
|
3448 "fully_frozen" AS "calculated"
|
jbe@532
|
3449 FROM "issue" WHERE "fully_frozen" NOTNULL
|
jbe@532
|
3450 ) AS "unordered"
|
jbe@532
|
3451 ORDER BY "calculated", "issue_id", "event"
|
jbe@532
|
3452 ) AS "ordered";
|
jbe@532
|
3453
|
jbe@532
|
3454
|
jbe@532
|
3455 INSERT INTO "snapshot" ("id", "calculated", "population", "area_id", "issue_id")
|
jbe@532
|
3456 SELECT
|
jbe@532
|
3457 "old_snapshot"."snapshot_id" AS "id",
|
jbe@532
|
3458 "old_snapshot"."calculated",
|
jbe@532
|
3459 ( SELECT COALESCE(sum("weight"), 0)
|
jbe@532
|
3460 FROM "direct_population_snapshot" "dps"
|
jbe@532
|
3461 WHERE "dps"."issue_id" = "old_snapshot"."issue_id"
|
jbe@532
|
3462 AND "dps"."event" = "old_snapshot"."event"
|
jbe@532
|
3463 ) AS "population",
|
jbe@532
|
3464 "issue"."area_id" AS "area_id",
|
jbe@532
|
3465 "issue"."id" AS "issue_id"
|
jbe@532
|
3466 FROM "old_snapshot" JOIN "issue"
|
jbe@532
|
3467 ON "old_snapshot"."issue_id" = "issue"."id";
|
jbe@532
|
3468
|
jbe@532
|
3469
|
jbe@532
|
3470 INSERT INTO "snapshot_issue" ("snapshot_id", "issue_id")
|
jbe@532
|
3471 SELECT "id" AS "snapshot_id", "issue_id" FROM "snapshot";
|
jbe@532
|
3472
|
jbe@532
|
3473
|
jbe@532
|
3474 INSERT INTO "snapshot_population" ("snapshot_id", "member_id")
|
jbe@532
|
3475 SELECT
|
jbe@532
|
3476 "old_snapshot"."snapshot_id",
|
jbe@532
|
3477 "direct_population_snapshot"."member_id"
|
jbe@532
|
3478 FROM "old_snapshot" JOIN "direct_population_snapshot"
|
jbe@532
|
3479 ON "old_snapshot"."issue_id" = "direct_population_snapshot"."issue_id"
|
jbe@532
|
3480 AND "old_snapshot"."event" = "direct_population_snapshot"."event";
|
jbe@532
|
3481
|
jbe@532
|
3482 INSERT INTO "snapshot_population" ("snapshot_id", "member_id")
|
jbe@532
|
3483 SELECT
|
jbe@532
|
3484 "old_snapshot"."snapshot_id",
|
jbe@532
|
3485 "delegating_population_snapshot"."member_id"
|
jbe@532
|
3486 FROM "old_snapshot" JOIN "delegating_population_snapshot"
|
jbe@532
|
3487 ON "old_snapshot"."issue_id" = "delegating_population_snapshot"."issue_id"
|
jbe@532
|
3488 AND "old_snapshot"."event" = "delegating_population_snapshot"."event";
|
jbe@532
|
3489
|
jbe@532
|
3490
|
jbe@532
|
3491 INSERT INTO "direct_interest_snapshot"
|
jbe@532
|
3492 ("snapshot_id", "issue_id", "member_id", "weight")
|
jbe@532
|
3493 SELECT
|
jbe@532
|
3494 "old_snapshot"."snapshot_id",
|
jbe@532
|
3495 "old_snapshot"."issue_id",
|
jbe@532
|
3496 "direct_interest_snapshot_old"."member_id",
|
jbe@532
|
3497 "direct_interest_snapshot_old"."weight"
|
jbe@532
|
3498 FROM "old_snapshot" JOIN "direct_interest_snapshot_old"
|
jbe@532
|
3499 ON "old_snapshot"."issue_id" = "direct_interest_snapshot_old"."issue_id"
|
jbe@532
|
3500 AND "old_snapshot"."event" = "direct_interest_snapshot_old"."event";
|
jbe@532
|
3501
|
jbe@532
|
3502 INSERT INTO "delegating_interest_snapshot"
|
jbe@532
|
3503 ( "snapshot_id", "issue_id",
|
jbe@532
|
3504 "member_id", "weight", "scope", "delegate_member_ids" )
|
jbe@532
|
3505 SELECT
|
jbe@532
|
3506 "old_snapshot"."snapshot_id",
|
jbe@532
|
3507 "old_snapshot"."issue_id",
|
jbe@532
|
3508 "delegating_interest_snapshot_old"."member_id",
|
jbe@532
|
3509 "delegating_interest_snapshot_old"."weight",
|
jbe@532
|
3510 "delegating_interest_snapshot_old"."scope",
|
jbe@532
|
3511 "delegating_interest_snapshot_old"."delegate_member_ids"
|
jbe@532
|
3512 FROM "old_snapshot" JOIN "delegating_interest_snapshot_old"
|
jbe@532
|
3513 ON "old_snapshot"."issue_id" = "delegating_interest_snapshot_old"."issue_id"
|
jbe@532
|
3514 AND "old_snapshot"."event" = "delegating_interest_snapshot_old"."event";
|
jbe@532
|
3515
|
jbe@532
|
3516 INSERT INTO "direct_supporter_snapshot"
|
jbe@532
|
3517 ( "snapshot_id", "issue_id",
|
jbe@532
|
3518 "initiative_id", "member_id", "draft_id", "informed", "satisfied" )
|
jbe@532
|
3519 SELECT
|
jbe@532
|
3520 "old_snapshot"."snapshot_id",
|
jbe@532
|
3521 "old_snapshot"."issue_id",
|
jbe@532
|
3522 "direct_supporter_snapshot_old"."initiative_id",
|
jbe@532
|
3523 "direct_supporter_snapshot_old"."member_id",
|
jbe@532
|
3524 "direct_supporter_snapshot_old"."draft_id",
|
jbe@532
|
3525 "direct_supporter_snapshot_old"."informed",
|
jbe@532
|
3526 "direct_supporter_snapshot_old"."satisfied"
|
jbe@532
|
3527 FROM "old_snapshot" JOIN "direct_supporter_snapshot_old"
|
jbe@532
|
3528 ON "old_snapshot"."issue_id" = "direct_supporter_snapshot_old"."issue_id"
|
jbe@532
|
3529 AND "old_snapshot"."event" = "direct_supporter_snapshot_old"."event";
|
jbe@532
|
3530
|
jbe@532
|
3531
|
jbe@532
|
3532 ALTER TABLE "issue" DISABLE TRIGGER USER; -- NOTE: required to modify table later
|
jbe@532
|
3533
|
jbe@532
|
3534 UPDATE "issue" SET "latest_snapshot_id" = "snapshot"."id"
|
jbe@532
|
3535 FROM (
|
jbe@532
|
3536 SELECT DISTINCT ON ("issue_id") "issue_id", "id"
|
jbe@532
|
3537 FROM "snapshot" ORDER BY "issue_id", "id" DESC
|
jbe@532
|
3538 ) AS "snapshot"
|
jbe@532
|
3539 WHERE "snapshot"."issue_id" = "issue"."id";
|
jbe@532
|
3540
|
jbe@532
|
3541 UPDATE "issue" SET "admission_snapshot_id" = "old_snapshot"."snapshot_id"
|
jbe@532
|
3542 FROM "old_snapshot"
|
jbe@532
|
3543 WHERE "old_snapshot"."issue_id" = "issue"."id"
|
jbe@532
|
3544 AND "old_snapshot"."event" = 'end_of_admission';
|
jbe@532
|
3545
|
jbe@532
|
3546 UPDATE "issue" SET "half_freeze_snapshot_id" = "old_snapshot"."snapshot_id"
|
jbe@532
|
3547 FROM "old_snapshot"
|
jbe@532
|
3548 WHERE "old_snapshot"."issue_id" = "issue"."id"
|
jbe@532
|
3549 AND "old_snapshot"."event" = 'half_freeze';
|
jbe@532
|
3550
|
jbe@532
|
3551 UPDATE "issue" SET "full_freeze_snapshot_id" = "old_snapshot"."snapshot_id"
|
jbe@532
|
3552 FROM "old_snapshot"
|
jbe@532
|
3553 WHERE "old_snapshot"."issue_id" = "issue"."id"
|
jbe@532
|
3554 AND "old_snapshot"."event" = 'full_freeze';
|
jbe@532
|
3555
|
jbe@532
|
3556 ALTER TABLE "issue" ENABLE TRIGGER USER;
|
jbe@532
|
3557
|
jbe@532
|
3558
|
jbe@532
|
3559 DROP TABLE "old_snapshot";
|
jbe@532
|
3560
|
jbe@532
|
3561 DROP TABLE "direct_supporter_snapshot_old";
|
jbe@532
|
3562 DROP TABLE "delegating_interest_snapshot_old";
|
jbe@532
|
3563 DROP TABLE "direct_interest_snapshot_old";
|
jbe@532
|
3564 DROP TABLE "delegating_population_snapshot";
|
jbe@532
|
3565 DROP TABLE "direct_population_snapshot";
|
jbe@532
|
3566
|
jbe@532
|
3567
|
jbe@532
|
3568 DROP VIEW "open_issue";
|
jbe@532
|
3569
|
jbe@532
|
3570
|
jbe@532
|
3571 ALTER TABLE "issue" DROP COLUMN "latest_snapshot_event";
|
jbe@532
|
3572
|
jbe@532
|
3573
|
jbe@532
|
3574 CREATE VIEW "open_issue" AS
|
jbe@532
|
3575 SELECT * FROM "issue" WHERE "closed" ISNULL;
|
jbe@532
|
3576
|
jbe@532
|
3577 COMMENT ON VIEW "open_issue" IS 'All open issues';
|
jbe@532
|
3578
|
jbe@532
|
3579
|
jbe@532
|
3580 -- NOTE: create "issue_for_admission" view after altering table "issue"
|
jbe@532
|
3581 CREATE VIEW "issue_for_admission" AS
|
jbe@532
|
3582 SELECT DISTINCT ON ("issue"."area_id")
|
jbe@532
|
3583 "issue".*,
|
jbe@532
|
3584 max("initiative"."supporter_count") AS "max_supporter_count"
|
jbe@532
|
3585 FROM "issue"
|
jbe@532
|
3586 JOIN "policy" ON "issue"."policy_id" = "policy"."id"
|
jbe@532
|
3587 JOIN "initiative" ON "issue"."id" = "initiative"."issue_id"
|
jbe@532
|
3588 JOIN "area" ON "issue"."area_id" = "area"."id"
|
jbe@532
|
3589 WHERE "issue"."state" = 'admission'::"issue_state"
|
jbe@532
|
3590 AND now() >= "issue"."created" + "issue"."min_admission_time"
|
jbe@532
|
3591 AND "initiative"."supporter_count" >= "policy"."issue_quorum"
|
jbe@532
|
3592 AND "initiative"."supporter_count" * "policy"."issue_quorum_den" >=
|
jbe@532
|
3593 "issue"."population" * "policy"."issue_quorum_num"
|
jbe@532
|
3594 AND "initiative"."supporter_count" >= "area"."issue_quorum"
|
jbe@532
|
3595 AND "initiative"."revoked" ISNULL
|
jbe@532
|
3596 GROUP BY "issue"."id"
|
jbe@532
|
3597 ORDER BY "issue"."area_id", "max_supporter_count" DESC, "issue"."id";
|
jbe@532
|
3598
|
jbe@532
|
3599 COMMENT ON VIEW "issue_for_admission" IS 'Contains up to 1 issue per area eligible to pass from ''admission'' to ''discussion'' state; needs to be recalculated after admitting the issue in this view';
|
jbe@532
|
3600
|
jbe@532
|
3601
|
jbe@532
|
3602 DROP TYPE "snapshot_event";
|
jbe@532
|
3603
|
jbe@532
|
3604
|
jbe@532
|
3605 ALTER TABLE "issue" ADD CONSTRAINT "snapshot_required" CHECK (
|
jbe@532
|
3606 ("half_frozen" ISNULL OR "half_freeze_snapshot_id" NOTNULL) AND
|
jbe@532
|
3607 ("fully_frozen" ISNULL OR "full_freeze_snapshot_id" NOTNULL) );
|
jbe@532
|
3608
|
jbe@532
|
3609
|
jbe@532
|
3610 COMMIT;
|