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