rev |
line source |
jbe@478
|
1 BEGIN;
|
jbe@478
|
2
|
jbe@478
|
3 CREATE OR REPLACE VIEW "liquid_feedback_version" AS
|
jbe@517
|
4 SELECT * FROM (VALUES ('3.2.1', 3, 2, 1))
|
jbe@478
|
5 AS "subquery"("string", "major", "minor", "revision");
|
jbe@478
|
6
|
jbe@510
|
7 ALTER TABLE "member" ADD COLUMN "disable_notifications" BOOLEAN NOT NULL DEFAULT FALSE;
|
jbe@510
|
8 ALTER TABLE "member" ADD COLUMN "notification_counter" INT4 NOT NULL DEFAULT 1;
|
jbe@510
|
9 ALTER TABLE "member" ADD COLUMN "notification_sample_size" INT4 NOT NULL DEFAULT 3;
|
jbe@510
|
10 ALTER TABLE "member" ADD COLUMN "notification_dow" INT4 CHECK ("notification_dow" BETWEEN 0 AND 6);
|
jbe@515
|
11 ALTER TABLE "member" ADD COLUMN "notification_hour" INT4 DEFAULT floor(random() * 24) CHECK ("notification_hour" BETWEEN 0 AND 23);
|
jbe@510
|
12 ALTER TABLE "member" ADD COLUMN "notification_sent" TIMESTAMP;
|
jbe@510
|
13 ALTER TABLE "member" ADD
|
jbe@510
|
14 CONSTRAINT "notification_dow_requires_notification_hour"
|
jbe@510
|
15 CHECK ("notification_dow" ISNULL OR "notification_hour" NOTNULL);
|
jbe@499
|
16
|
jbe@510
|
17 UPDATE "member" SET "disable_notifications" = TRUE WHERE "notify_level" = 'none'::"notify_level";
|
jbe@478
|
18
|
jbe@512
|
19 DROP VIEW "selected_event_seen_by_member";
|
jbe@512
|
20 DROP VIEW "event_seen_by_member";
|
jbe@512
|
21
|
jbe@510
|
22 ALTER TABLE "member" DROP COLUMN "notify_level";
|
jbe@499
|
23
|
jbe@499
|
24 DROP TYPE "notify_level";
|
jbe@510
|
25
|
jbe@510
|
26 COMMENT ON COLUMN "member"."disable_notifications" IS 'TRUE if member does not want to receive notifications';
|
jbe@510
|
27 COMMENT ON COLUMN "member"."notification_counter" IS 'Sequential number of next scheduled notification message (used as a seed for pseudo-random initiative selection algorithm)';
|
jbe@510
|
28 COMMENT ON COLUMN "member"."notification_sample_size" IS 'Number of featured initiatives per issue in scheduled notification messages';
|
jbe@510
|
29 COMMENT ON COLUMN "member"."notification_dow" IS 'Day of week for scheduled notifications (NULL to receive a daily digest)';
|
jbe@510
|
30 COMMENT ON COLUMN "member"."notification_hour" IS 'Time of day when scheduled notifications are sent out';
|
jbe@510
|
31 COMMENT ON COLUMN "member"."notification_sent" IS 'Timestamp of last scheduled notification mail that has been sent out';
|
jbe@510
|
32
|
jbe@510
|
33 ALTER TABLE "rendered_member_statement" ALTER COLUMN "member_id" SET DATA TYPE INT4;
|
jbe@513
|
34
|
jbe@513
|
35 DROP VIEW "expired_session";
|
jbe@513
|
36
|
jbe@510
|
37 ALTER TABLE "session" ALTER COLUMN "member_id" SET DATA TYPE INT4;
|
jbe@510
|
38
|
jbe@513
|
39 CREATE VIEW "expired_session" AS
|
jbe@513
|
40 SELECT * FROM "session" WHERE now() > "expiry";
|
jbe@513
|
41 CREATE RULE "delete" AS ON DELETE TO "expired_session" DO INSTEAD
|
jbe@513
|
42 DELETE FROM "session" WHERE "ident" = OLD."ident";
|
jbe@513
|
43
|
jbe@513
|
44 COMMENT ON VIEW "expired_session" IS 'View containing all expired sessions where DELETE is possible';
|
jbe@513
|
45 COMMENT ON RULE "delete" ON "expired_session" IS 'Rule allowing DELETE on rows in "expired_session" view, i.e. DELETE FROM "expired_session"';
|
jbe@513
|
46
|
jbe@478
|
47 CREATE TABLE "subscription" (
|
jbe@478
|
48 PRIMARY KEY ("member_id", "unit_id"),
|
jbe@478
|
49 "member_id" INT4 REFERENCES "member" ("id") ON DELETE CASCADE ON UPDATE CASCADE,
|
jbe@478
|
50 "unit_id" INT4 REFERENCES "unit" ("id") ON DELETE CASCADE ON UPDATE CASCADE );
|
jbe@478
|
51 CREATE INDEX "subscription_unit_id_idx" ON "subscription" ("unit_id");
|
jbe@492
|
52
|
jbe@492
|
53 COMMENT ON TABLE "subscription" IS 'An entry in this table denotes that the member wishes to receive notifications regardless of his/her privileges in the given unit';
|
jbe@492
|
54
|
jbe@492
|
55 CREATE TABLE "ignored_area" (
|
jbe@492
|
56 PRIMARY KEY ("member_id", "area_id"),
|
jbe@492
|
57 "member_id" INT4 REFERENCES "unit" ("id") ON DELETE CASCADE ON UPDATE CASCADE,
|
jbe@492
|
58 "area_id" INT4 REFERENCES "area" ("id") ON DELETE CASCADE ON UPDATE CASCADE );
|
jbe@492
|
59 CREATE INDEX "ignored_area_area_id_idx" ON "ignored_area" ("area_id");
|
jbe@492
|
60
|
jbe@492
|
61 COMMENT ON TABLE "ignored_area" IS 'An entry in this table denotes that the member does not wish to receive notifications for the given subject area unless he/she declared interested in a particular issue';
|
jbe@492
|
62
|
jbe@510
|
63 ALTER TABLE "ignored_initiative" DROP CONSTRAINT "ignored_initiative_pkey";
|
jbe@510
|
64 DROP INDEX "ignored_initiative_member_id_idx";
|
jbe@510
|
65
|
jbe@510
|
66 ALTER TABLE "ignored_initiative" ADD PRIMARY KEY ("member_id", "initiative_id");
|
jbe@510
|
67 CREATE INDEX "ignored_initiative_initiative_id_idx" ON "ignored_initiative" ("initiative_id");
|
jbe@510
|
68
|
jbe@510
|
69 COMMENT ON TABLE "ignored_initiative" IS 'An entry in this table denotes that the member does not wish to receive notifications for the given initiative';
|
jbe@510
|
70
|
jbe@510
|
71 ALTER TABLE "notification_sent" RENAME TO "notification_event_sent";
|
jbe@510
|
72 ALTER INDEX "notification_sent_singleton_idx" RENAME TO "notification_event_sent_singleton_idx";
|
jbe@510
|
73
|
jbe@510
|
74 CREATE TABLE "notification_initiative_sent" (
|
jbe@492
|
75 PRIMARY KEY ("member_id", "initiative_id"),
|
jbe@492
|
76 "member_id" INT4 REFERENCES "member" ("id") ON DELETE CASCADE ON UPDATE CASCADE,
|
jbe@492
|
77 "initiative_id" INT4 REFERENCES "initiative" ("id") ON DELETE CASCADE ON UPDATE CASCADE,
|
jbe@492
|
78 "last_draft_id" INT8 NOT NULL,
|
jbe@495
|
79 "last_suggestion_id" INT8 );
|
jbe@510
|
80 CREATE INDEX "notification_initiative_sent_initiative_idx" ON "notification_initiative_sent" ("initiative_id");
|
jbe@510
|
81
|
jbe@510
|
82 COMMENT ON TABLE "notification_initiative_sent" IS 'Information which initiatives have been promoted to a member in a scheduled notification mail';
|
jbe@510
|
83
|
jbe@510
|
84 COMMENT ON COLUMN "notification_initiative_sent"."last_draft_id" IS 'Current (i.e. last) draft_id when initiative had been promoted';
|
jbe@510
|
85 COMMENT ON COLUMN "notification_initiative_sent"."last_suggestion_id" IS 'Current (i.e. last) draft_id when initiative had been promoted';
|
jbe@478
|
86
|
jbe@496
|
87 CREATE TABLE "newsletter" (
|
jbe@496
|
88 "id" SERIAL4 PRIMARY KEY,
|
jbe@496
|
89 "published" TIMESTAMPTZ NOT NULL,
|
jbe@496
|
90 "unit_id" INT4 REFERENCES "unit" ("id") ON DELETE CASCADE ON UPDATE CASCADE,
|
jbe@496
|
91 "include_all_members" BOOLEAN NOT NULL,
|
jbe@496
|
92 "sent" TIMESTAMPTZ,
|
jbe@496
|
93 "subject" TEXT NOT NULL,
|
jbe@496
|
94 "content" TEXT NOT NULL );
|
jbe@496
|
95 CREATE INDEX "newsletter_unit_id_idx" ON "newsletter" ("unit_id", "published");
|
jbe@496
|
96 CREATE INDEX "newsletter_all_units_published_idx" ON "newsletter" ("published") WHERE "unit_id" ISNULL;
|
jbe@496
|
97 CREATE INDEX "newsletter_published_idx" ON "newsletter" ("published");
|
jbe@496
|
98
|
jbe@510
|
99 COMMENT ON TABLE "newsletter" IS 'Contains newsletters created by administrators to be sent out and for further reference';
|
jbe@510
|
100
|
jbe@510
|
101 COMMENT ON COLUMN "newsletter"."published" IS 'Timestamp when the newsletter is to be sent out (and made available in the frontend)';
|
jbe@510
|
102 COMMENT ON COLUMN "newsletter"."unit_id" IS 'If set, only members with voting right in the given unit are considered to be recipients';
|
jbe@510
|
103 COMMENT ON COLUMN "newsletter"."include_all_members" IS 'TRUE = include all members regardless of their ''disable_notifications'' setting';
|
jbe@510
|
104 COMMENT ON COLUMN "newsletter"."sent" IS 'Timestamp when the newsletter has been mailed out';
|
jbe@510
|
105 COMMENT ON COLUMN "newsletter"."subject" IS 'Subject line (e.g. to be used for the email)';
|
jbe@510
|
106 COMMENT ON COLUMN "newsletter"."content" IS 'Plain text content of the newsletter';
|
jbe@510
|
107
|
jbe@510
|
108 CREATE OR REPLACE FUNCTION "issue_requires_first_initiative_trigger"()
|
jbe@510
|
109 RETURNS TRIGGER
|
jbe@510
|
110 LANGUAGE 'plpgsql' VOLATILE AS $$
|
jbe@510
|
111 BEGIN
|
jbe@510
|
112 IF NOT EXISTS (
|
jbe@510
|
113 SELECT NULL FROM "initiative" WHERE "issue_id" = NEW."id"
|
jbe@510
|
114 ) THEN
|
jbe@510
|
115 RAISE EXCEPTION 'Cannot create issue without an initial initiative.' USING
|
jbe@510
|
116 ERRCODE = 'integrity_constraint_violation',
|
jbe@510
|
117 HINT = 'Create issue, initiative, and draft within the same transaction.';
|
jbe@510
|
118 END IF;
|
jbe@510
|
119 RETURN NULL;
|
jbe@510
|
120 END;
|
jbe@510
|
121 $$;
|
jbe@510
|
122
|
jbe@510
|
123 CREATE OR REPLACE FUNCTION "initiative_requires_first_draft_trigger"()
|
jbe@510
|
124 RETURNS TRIGGER
|
jbe@510
|
125 LANGUAGE 'plpgsql' VOLATILE AS $$
|
jbe@510
|
126 BEGIN
|
jbe@510
|
127 IF NOT EXISTS (
|
jbe@510
|
128 SELECT NULL FROM "draft" WHERE "initiative_id" = NEW."id"
|
jbe@510
|
129 ) THEN
|
jbe@510
|
130 RAISE EXCEPTION 'Cannot create initiative without an initial draft.' USING
|
jbe@510
|
131 ERRCODE = 'integrity_constraint_violation',
|
jbe@510
|
132 HINT = 'Create issue, initiative and draft within the same transaction.';
|
jbe@510
|
133 END IF;
|
jbe@510
|
134 RETURN NULL;
|
jbe@510
|
135 END;
|
jbe@510
|
136 $$;
|
jbe@510
|
137
|
jbe@510
|
138 CREATE OR REPLACE FUNCTION "suggestion_requires_first_opinion_trigger"()
|
jbe@510
|
139 RETURNS TRIGGER
|
jbe@510
|
140 LANGUAGE 'plpgsql' VOLATILE AS $$
|
jbe@510
|
141 BEGIN
|
jbe@510
|
142 IF NOT EXISTS (
|
jbe@510
|
143 SELECT NULL FROM "opinion" WHERE "suggestion_id" = NEW."id"
|
jbe@510
|
144 ) THEN
|
jbe@510
|
145 RAISE EXCEPTION 'Cannot create a suggestion without an opinion.' USING
|
jbe@510
|
146 ERRCODE = 'integrity_constraint_violation',
|
jbe@510
|
147 HINT = 'Create suggestion and opinion within the same transaction.';
|
jbe@510
|
148 END IF;
|
jbe@510
|
149 RETURN NULL;
|
jbe@510
|
150 END;
|
jbe@510
|
151 $$;
|
jbe@510
|
152
|
jbe@510
|
153 CREATE OR REPLACE FUNCTION "forbid_changes_on_closed_issue_trigger"()
|
jbe@510
|
154 RETURNS TRIGGER
|
jbe@510
|
155 LANGUAGE 'plpgsql' VOLATILE AS $$
|
jbe@510
|
156 DECLARE
|
jbe@510
|
157 "issue_id_v" "issue"."id"%TYPE;
|
jbe@510
|
158 "issue_row" "issue"%ROWTYPE;
|
jbe@510
|
159 BEGIN
|
jbe@510
|
160 IF EXISTS (
|
jbe@510
|
161 SELECT NULL FROM "temporary_transaction_data"
|
jbe@510
|
162 WHERE "txid" = txid_current()
|
jbe@510
|
163 AND "key" = 'override_protection_triggers'
|
jbe@510
|
164 AND "value" = TRUE::TEXT
|
jbe@510
|
165 ) THEN
|
jbe@510
|
166 RETURN NULL;
|
jbe@510
|
167 END IF;
|
jbe@510
|
168 IF TG_OP = 'DELETE' THEN
|
jbe@510
|
169 "issue_id_v" := OLD."issue_id";
|
jbe@510
|
170 ELSE
|
jbe@510
|
171 "issue_id_v" := NEW."issue_id";
|
jbe@510
|
172 END IF;
|
jbe@510
|
173 SELECT INTO "issue_row" * FROM "issue"
|
jbe@510
|
174 WHERE "id" = "issue_id_v" FOR SHARE;
|
jbe@510
|
175 IF (
|
jbe@510
|
176 "issue_row"."closed" NOTNULL OR (
|
jbe@510
|
177 "issue_row"."state" = 'voting' AND
|
jbe@510
|
178 "issue_row"."phase_finished" NOTNULL
|
jbe@510
|
179 )
|
jbe@510
|
180 ) THEN
|
jbe@510
|
181 IF
|
jbe@510
|
182 TG_RELID = 'direct_voter'::regclass AND
|
jbe@510
|
183 TG_OP = 'UPDATE'
|
jbe@510
|
184 THEN
|
jbe@510
|
185 IF
|
jbe@510
|
186 OLD."issue_id" = NEW."issue_id" AND
|
jbe@510
|
187 OLD."member_id" = NEW."member_id" AND
|
jbe@510
|
188 OLD."weight" = NEW."weight"
|
jbe@510
|
189 THEN
|
jbe@510
|
190 RETURN NULL; -- allows changing of voter comment
|
jbe@510
|
191 END IF;
|
jbe@510
|
192 END IF;
|
jbe@510
|
193 RAISE EXCEPTION 'Tried to modify data after voting has been closed.' USING
|
jbe@510
|
194 ERRCODE = 'integrity_constraint_violation';
|
jbe@510
|
195 END IF;
|
jbe@510
|
196 RETURN NULL;
|
jbe@510
|
197 END;
|
jbe@510
|
198 $$;
|
jbe@510
|
199
|
jbe@499
|
200 CREATE VIEW "event_for_notification" AS
|
jbe@499
|
201 SELECT
|
jbe@499
|
202 "member"."id" AS "recipient_id",
|
jbe@499
|
203 "event".*
|
jbe@499
|
204 FROM "member" CROSS JOIN "event"
|
jbe@499
|
205 JOIN "issue" ON "issue"."id" = "event"."issue_id"
|
jbe@499
|
206 JOIN "area" ON "area"."id" = "issue"."area_id"
|
jbe@499
|
207 LEFT JOIN "privilege" ON
|
jbe@499
|
208 "privilege"."member_id" = "member"."id" AND
|
jbe@499
|
209 "privilege"."unit_id" = "area"."unit_id" AND
|
jbe@499
|
210 "privilege"."voting_right" = TRUE
|
jbe@499
|
211 LEFT JOIN "subscription" ON
|
jbe@499
|
212 "subscription"."member_id" = "member"."id" AND
|
jbe@499
|
213 "subscription"."unit_id" = "area"."unit_id"
|
jbe@499
|
214 LEFT JOIN "ignored_area" ON
|
jbe@499
|
215 "ignored_area"."member_id" = "member"."id" AND
|
jbe@499
|
216 "ignored_area"."area_id" = "issue"."area_id"
|
jbe@499
|
217 LEFT JOIN "interest" ON
|
jbe@499
|
218 "interest"."member_id" = "member"."id" AND
|
jbe@499
|
219 "interest"."issue_id" = "event"."issue_id"
|
jbe@499
|
220 LEFT JOIN "supporter" ON
|
jbe@499
|
221 "supporter"."member_id" = "member"."id" AND
|
jbe@499
|
222 "supporter"."initiative_id" = "event"."initiative_id"
|
jbe@499
|
223 WHERE ("privilege"."member_id" NOTNULL OR "subscription"."member_id" NOTNULL)
|
jbe@499
|
224 AND ("ignored_area"."member_id" ISNULL OR "interest"."member_id" NOTNULL)
|
jbe@499
|
225 AND (
|
jbe@499
|
226 "event"."event" = 'issue_state_changed'::"event_type" OR
|
jbe@499
|
227 ( "event"."event" = 'initiative_revoked'::"event_type" AND
|
jbe@499
|
228 "supporter"."member_id" NOTNULL ) );
|
jbe@499
|
229
|
jbe@510
|
230 COMMENT ON VIEW "event_for_notification" IS 'Entries of the "event" table which are of interest for a particular notification mail recipient';
|
jbe@510
|
231
|
jbe@510
|
232 COMMENT ON COLUMN "event_for_notification"."recipient_id" IS 'member_id of the recipient of a notification mail';
|
jbe@510
|
233
|
jbe@478
|
234 CREATE VIEW "updated_initiative" AS
|
jbe@478
|
235 SELECT
|
jbe@499
|
236 "supporter"."member_id" AS "recipient_id",
|
jbe@478
|
237 FALSE AS "featured",
|
jbe@499
|
238 "supporter"."initiative_id"
|
jbe@499
|
239 FROM "supporter"
|
jbe@499
|
240 JOIN "initiative" ON "supporter"."initiative_id" = "initiative"."id"
|
jbe@478
|
241 JOIN "issue" ON "issue"."id" = "initiative"."issue_id"
|
jbe@510
|
242 LEFT JOIN "notification_initiative_sent" AS "sent" ON
|
jbe@499
|
243 "sent"."member_id" = "supporter"."member_id" AND
|
jbe@499
|
244 "sent"."initiative_id" = "supporter"."initiative_id"
|
jbe@499
|
245 LEFT JOIN "ignored_initiative" ON
|
jbe@499
|
246 "ignored_initiative"."member_id" = "supporter"."member_id" AND
|
jbe@499
|
247 "ignored_initiative"."initiative_id" = "supporter"."initiative_id"
|
jbe@480
|
248 WHERE "issue"."state" IN ('admission', 'discussion')
|
jbe@503
|
249 AND "initiative"."revoked" ISNULL
|
jbe@499
|
250 AND "ignored_initiative"."member_id" ISNULL
|
jbe@478
|
251 AND (
|
jbe@478
|
252 EXISTS (
|
jbe@478
|
253 SELECT NULL FROM "draft"
|
jbe@499
|
254 LEFT JOIN "ignored_member" ON
|
jbe@499
|
255 "ignored_member"."member_id" = "supporter"."member_id" AND
|
jbe@499
|
256 "ignored_member"."other_member_id" = "draft"."author_id"
|
jbe@499
|
257 WHERE "draft"."initiative_id" = "supporter"."initiative_id"
|
jbe@478
|
258 AND "draft"."id" > "supporter"."draft_id"
|
jbe@499
|
259 AND "ignored_member"."member_id" ISNULL
|
jbe@478
|
260 ) OR EXISTS (
|
jbe@478
|
261 SELECT NULL FROM "suggestion"
|
jbe@492
|
262 LEFT JOIN "opinion" ON
|
jbe@492
|
263 "opinion"."member_id" = "supporter"."member_id" AND
|
jbe@492
|
264 "opinion"."suggestion_id" = "suggestion"."id"
|
jbe@499
|
265 LEFT JOIN "ignored_member" ON
|
jbe@499
|
266 "ignored_member"."member_id" = "supporter"."member_id" AND
|
jbe@499
|
267 "ignored_member"."other_member_id" = "suggestion"."author_id"
|
jbe@499
|
268 WHERE "suggestion"."initiative_id" = "supporter"."initiative_id"
|
jbe@492
|
269 AND "opinion"."member_id" ISNULL
|
jbe@499
|
270 AND COALESCE("suggestion"."id" > "sent"."last_suggestion_id", TRUE)
|
jbe@499
|
271 AND "ignored_member"."member_id" ISNULL
|
jbe@478
|
272 )
|
jbe@478
|
273 );
|
jbe@478
|
274
|
jbe@510
|
275 COMMENT ON VIEW "updated_initiative" IS 'Helper view for view "updated_or_featured_initiative"';
|
jbe@510
|
276
|
jbe@478
|
277 CREATE FUNCTION "featured_initiative"
|
jbe@499
|
278 ( "recipient_id_p" "member"."id"%TYPE,
|
jbe@499
|
279 "area_id_p" "area"."id"%TYPE )
|
jbe@499
|
280 RETURNS SETOF "initiative"."id"%TYPE
|
jbe@478
|
281 LANGUAGE 'plpgsql' STABLE AS $$
|
jbe@478
|
282 DECLARE
|
jbe@499
|
283 "counter_v" "member"."notification_counter"%TYPE;
|
jbe@499
|
284 "sample_size_v" "member"."notification_sample_size"%TYPE;
|
jbe@499
|
285 "initiative_id_ary" INT4[]; --"initiative"."id"%TYPE[]
|
jbe@499
|
286 "match_v" BOOLEAN;
|
jbe@478
|
287 "member_id_v" "member"."id"%TYPE;
|
jbe@478
|
288 "seed_v" TEXT;
|
jbe@499
|
289 "initiative_id_v" "initiative"."id"%TYPE;
|
jbe@478
|
290 BEGIN
|
jbe@499
|
291 SELECT "notification_counter", "notification_sample_size"
|
jbe@499
|
292 INTO "counter_v", "sample_size_v"
|
jbe@499
|
293 FROM "member" WHERE "id" = "recipient_id_p";
|
jbe@478
|
294 "initiative_id_ary" := '{}';
|
jbe@478
|
295 LOOP
|
jbe@478
|
296 "match_v" := FALSE;
|
jbe@478
|
297 FOR "member_id_v", "seed_v" IN
|
jbe@478
|
298 SELECT * FROM (
|
jbe@478
|
299 SELECT DISTINCT
|
jbe@478
|
300 "supporter"."member_id",
|
jbe@499
|
301 md5(
|
jbe@499
|
302 "recipient_id_p" || '-' ||
|
jbe@499
|
303 "counter_v" || '-' ||
|
jbe@499
|
304 "area_id_p" || '-' ||
|
jbe@499
|
305 "supporter"."member_id"
|
jbe@499
|
306 ) AS "seed"
|
jbe@478
|
307 FROM "supporter"
|
jbe@478
|
308 JOIN "initiative" ON "initiative"."id" = "supporter"."initiative_id"
|
jbe@478
|
309 JOIN "issue" ON "issue"."id" = "initiative"."issue_id"
|
jbe@499
|
310 WHERE "supporter"."member_id" != "recipient_id_p"
|
jbe@478
|
311 AND "issue"."area_id" = "area_id_p"
|
jbe@478
|
312 AND "issue"."state" IN ('admission', 'discussion', 'verification')
|
jbe@478
|
313 ) AS "subquery"
|
jbe@478
|
314 ORDER BY "seed"
|
jbe@478
|
315 LOOP
|
jbe@499
|
316 SELECT "initiative"."id" INTO "initiative_id_v"
|
jbe@478
|
317 FROM "initiative"
|
jbe@478
|
318 JOIN "issue" ON "issue"."id" = "initiative"."issue_id"
|
jbe@499
|
319 JOIN "area" ON "area"."id" = "issue"."area_id"
|
jbe@478
|
320 JOIN "supporter" ON "supporter"."initiative_id" = "initiative"."id"
|
jbe@478
|
321 LEFT JOIN "supporter" AS "self_support" ON
|
jbe@478
|
322 "self_support"."initiative_id" = "initiative"."id" AND
|
jbe@499
|
323 "self_support"."member_id" = "recipient_id_p"
|
jbe@499
|
324 LEFT JOIN "privilege" ON
|
jbe@499
|
325 "privilege"."member_id" = "recipient_id_p" AND
|
jbe@499
|
326 "privilege"."unit_id" = "area"."unit_id" AND
|
jbe@499
|
327 "privilege"."voting_right" = TRUE
|
jbe@499
|
328 LEFT JOIN "subscription" ON
|
jbe@499
|
329 "subscription"."member_id" = "recipient_id_p" AND
|
jbe@499
|
330 "subscription"."unit_id" = "area"."unit_id"
|
jbe@499
|
331 LEFT JOIN "ignored_initiative" ON
|
jbe@499
|
332 "ignored_initiative"."member_id" = "recipient_id_p" AND
|
jbe@499
|
333 "ignored_initiative"."initiative_id" = "initiative"."id"
|
jbe@478
|
334 WHERE "supporter"."member_id" = "member_id_v"
|
jbe@478
|
335 AND "issue"."area_id" = "area_id_p"
|
jbe@478
|
336 AND "issue"."state" IN ('admission', 'discussion', 'verification')
|
jbe@503
|
337 AND "initiative"."revoked" ISNULL
|
jbe@478
|
338 AND "self_support"."member_id" ISNULL
|
jbe@478
|
339 AND NOT "initiative_id_ary" @> ARRAY["initiative"."id"]
|
jbe@499
|
340 AND (
|
jbe@499
|
341 "privilege"."member_id" NOTNULL OR
|
jbe@499
|
342 "subscription"."member_id" NOTNULL )
|
jbe@499
|
343 AND "ignored_initiative"."member_id" ISNULL
|
jbe@499
|
344 AND NOT EXISTS (
|
jbe@499
|
345 SELECT NULL FROM "draft"
|
jbe@499
|
346 JOIN "ignored_member" ON
|
jbe@499
|
347 "ignored_member"."member_id" = "recipient_id_p" AND
|
jbe@499
|
348 "ignored_member"."other_member_id" = "draft"."author_id"
|
jbe@499
|
349 WHERE "draft"."initiative_id" = "initiative"."id"
|
jbe@499
|
350 )
|
jbe@478
|
351 ORDER BY md5("seed_v" || '-' || "initiative"."id")
|
jbe@478
|
352 LIMIT 1;
|
jbe@478
|
353 IF FOUND THEN
|
jbe@478
|
354 "match_v" := TRUE;
|
jbe@499
|
355 RETURN NEXT "initiative_id_v";
|
jbe@499
|
356 IF array_length("initiative_id_ary", 1) + 1 >= "sample_size_v" THEN
|
jbe@478
|
357 RETURN;
|
jbe@478
|
358 END IF;
|
jbe@499
|
359 "initiative_id_ary" := "initiative_id_ary" || "initiative_id_v";
|
jbe@478
|
360 END IF;
|
jbe@478
|
361 END LOOP;
|
jbe@478
|
362 EXIT WHEN NOT "match_v";
|
jbe@478
|
363 END LOOP;
|
jbe@478
|
364 RETURN;
|
jbe@478
|
365 END;
|
jbe@478
|
366 $$;
|
jbe@478
|
367
|
jbe@510
|
368 COMMENT ON FUNCTION "featured_initiative"
|
jbe@510
|
369 ( "recipient_id_p" "member"."id"%TYPE,
|
jbe@510
|
370 "area_id_p" "area"."id"%TYPE )
|
jbe@510
|
371 IS 'Helper function for view "updated_or_featured_initiative"';
|
jbe@510
|
372
|
jbe@478
|
373 CREATE VIEW "updated_or_featured_initiative" AS
|
jbe@478
|
374 SELECT
|
jbe@499
|
375 "subquery".*,
|
jbe@478
|
376 NOT EXISTS (
|
jbe@478
|
377 SELECT NULL FROM "initiative" AS "better_initiative"
|
jbe@499
|
378 WHERE "better_initiative"."issue_id" = "initiative"."issue_id"
|
jbe@484
|
379 AND
|
jbe@502
|
380 ( COALESCE("better_initiative"."supporter_count", -1),
|
jbe@484
|
381 -"better_initiative"."id" ) >
|
jbe@502
|
382 ( COALESCE("initiative"."supporter_count", -1),
|
jbe@485
|
383 -"initiative"."id" )
|
jbe@499
|
384 ) AS "leading"
|
jbe@499
|
385 FROM (
|
jbe@499
|
386 SELECT * FROM "updated_initiative"
|
jbe@499
|
387 UNION ALL
|
jbe@499
|
388 SELECT
|
jbe@499
|
389 "member"."id" AS "recipient_id",
|
jbe@499
|
390 TRUE AS "featured",
|
jbe@499
|
391 "featured_initiative_id" AS "initiative_id"
|
jbe@499
|
392 FROM "member" CROSS JOIN "area"
|
jbe@499
|
393 CROSS JOIN LATERAL
|
jbe@499
|
394 "featured_initiative"("member"."id", "area"."id") AS "featured_initiative_id"
|
jbe@499
|
395 JOIN "initiative" ON "initiative"."id" = "featured_initiative_id"
|
jbe@499
|
396 ) AS "subquery"
|
jbe@499
|
397 JOIN "initiative" ON "initiative"."id" = "subquery"."initiative_id";
|
jbe@478
|
398
|
jbe@510
|
399 COMMENT ON VIEW "updated_or_featured_initiative" IS 'Initiatives to be included in a scheduled notification mail because (a) they have been updated or (b) they are featured';
|
jbe@510
|
400
|
jbe@510
|
401 COMMENT ON COLUMN "updated_or_featured_initiative"."recipient_id" IS '"id" of the member who receives the notification mail';
|
jbe@510
|
402 COMMENT ON COLUMN "updated_or_featured_initiative"."featured" IS 'TRUE if the initiative has been included because it was selected by the "featured_initiative" algorithm (see source of function "featured_initiative")';
|
jbe@510
|
403 COMMENT ON COLUMN "updated_or_featured_initiative"."initiative_id" IS '"id" of the initiative to be included in the notification mail';
|
jbe@510
|
404 COMMENT ON COLUMN "updated_or_featured_initiative"."leading" IS 'TRUE if the initiative has the highest "supporter_count" in the issue';
|
jbe@510
|
405
|
jbe@478
|
406 CREATE VIEW "leading_complement_initiative" AS
|
jbe@478
|
407 SELECT * FROM (
|
jbe@499
|
408 SELECT DISTINCT ON ("uf_initiative"."recipient_id", "initiative"."issue_id")
|
jbe@499
|
409 "uf_initiative"."recipient_id",
|
jbe@478
|
410 FALSE AS "featured",
|
jbe@499
|
411 "uf_initiative"."initiative_id",
|
jbe@499
|
412 TRUE AS "leading"
|
jbe@492
|
413 FROM "updated_or_featured_initiative" AS "uf_initiative"
|
jbe@499
|
414 JOIN "initiative" AS "uf_initiative_full" ON
|
jbe@499
|
415 "uf_initiative_full"."id" = "uf_initiative"."initiative_id"
|
jbe@492
|
416 JOIN "initiative" ON
|
jbe@499
|
417 "initiative"."issue_id" = "uf_initiative_full"."issue_id"
|
jbe@503
|
418 WHERE "initiative"."revoked" ISNULL
|
jbe@478
|
419 ORDER BY
|
jbe@499
|
420 "uf_initiative"."recipient_id",
|
jbe@478
|
421 "initiative"."issue_id",
|
jbe@502
|
422 "initiative"."supporter_count" DESC,
|
jbe@478
|
423 "initiative"."id"
|
jbe@478
|
424 ) AS "subquery"
|
jbe@478
|
425 WHERE NOT EXISTS (
|
jbe@478
|
426 SELECT NULL FROM "updated_or_featured_initiative" AS "other"
|
jbe@499
|
427 WHERE "other"."recipient_id" = "subquery"."recipient_id"
|
jbe@499
|
428 AND "other"."initiative_id" = "subquery"."initiative_id"
|
jbe@478
|
429 );
|
jbe@478
|
430
|
jbe@510
|
431 COMMENT ON VIEW "leading_complement_initiative" IS 'Helper view for view "unfiltered_initiative_for_notification" in order to always include the most supported initiative of an issue';
|
jbe@510
|
432 COMMENT ON COLUMN "leading_complement_initiative"."featured" IS 'Always FALSE in this view';
|
jbe@510
|
433 COMMENT ON COLUMN "leading_complement_initiative"."initiative_id" IS '"id" of the initiative to be included in the notification mail';
|
jbe@510
|
434 COMMENT ON COLUMN "leading_complement_initiative"."leading" IS 'Always TRUE in this view';
|
jbe@510
|
435
|
jbe@492
|
436 CREATE VIEW "unfiltered_initiative_for_notification" AS
|
jbe@499
|
437 SELECT
|
jbe@499
|
438 "subquery".*,
|
jbe@499
|
439 "supporter"."member_id" NOTNULL AS "supported",
|
jbe@499
|
440 CASE WHEN "supporter"."member_id" NOTNULL THEN
|
jbe@499
|
441 EXISTS (
|
jbe@499
|
442 SELECT NULL FROM "draft"
|
jbe@499
|
443 WHERE "draft"."initiative_id" = "subquery"."initiative_id"
|
jbe@499
|
444 AND "draft"."id" > "supporter"."draft_id"
|
jbe@499
|
445 )
|
jbe@499
|
446 ELSE
|
jbe@499
|
447 EXISTS (
|
jbe@499
|
448 SELECT NULL FROM "draft"
|
jbe@499
|
449 WHERE "draft"."initiative_id" = "subquery"."initiative_id"
|
jbe@499
|
450 AND COALESCE("draft"."id" > "sent"."last_draft_id", TRUE)
|
jbe@499
|
451 )
|
jbe@499
|
452 END AS "new_draft",
|
jbe@499
|
453 CASE WHEN "supporter"."member_id" NOTNULL THEN
|
jbe@499
|
454 ( SELECT count(1) FROM "suggestion"
|
jbe@499
|
455 LEFT JOIN "opinion" ON
|
jbe@499
|
456 "opinion"."member_id" = "supporter"."member_id" AND
|
jbe@499
|
457 "opinion"."suggestion_id" = "suggestion"."id"
|
jbe@499
|
458 WHERE "suggestion"."initiative_id" = "subquery"."initiative_id"
|
jbe@499
|
459 AND "opinion"."member_id" ISNULL
|
jbe@499
|
460 AND COALESCE("suggestion"."id" > "sent"."last_suggestion_id", TRUE)
|
jbe@499
|
461 )
|
jbe@499
|
462 ELSE
|
jbe@499
|
463 ( SELECT count(1) FROM "suggestion"
|
jbe@499
|
464 WHERE "suggestion"."initiative_id" = "subquery"."initiative_id"
|
jbe@499
|
465 AND COALESCE("suggestion"."id" > "sent"."last_suggestion_id", TRUE)
|
jbe@499
|
466 )
|
jbe@499
|
467 END AS "new_suggestion_count"
|
jbe@499
|
468 FROM (
|
jbe@499
|
469 SELECT * FROM "updated_or_featured_initiative"
|
jbe@499
|
470 UNION ALL
|
jbe@499
|
471 SELECT * FROM "leading_complement_initiative"
|
jbe@499
|
472 ) AS "subquery"
|
jbe@499
|
473 LEFT JOIN "supporter" ON
|
jbe@499
|
474 "supporter"."member_id" = "subquery"."recipient_id" AND
|
jbe@499
|
475 "supporter"."initiative_id" = "subquery"."initiative_id"
|
jbe@510
|
476 LEFT JOIN "notification_initiative_sent" AS "sent" ON
|
jbe@499
|
477 "sent"."member_id" = "subquery"."recipient_id" AND
|
jbe@499
|
478 "sent"."initiative_id" = "subquery"."initiative_id";
|
jbe@478
|
479
|
jbe@510
|
480 COMMENT ON VIEW "unfiltered_initiative_for_notification" IS 'Helper view which simply combines the views "updated_or_featured_initiative" and "leading_complement_initiative" and adds columns "supported", "new_draft", and "new_suggestion_count';
|
jbe@510
|
481
|
jbe@510
|
482 COMMENT ON COLUMN "unfiltered_initiative_for_notification"."supported" IS 'TRUE if initiative is supported by the recipient';
|
jbe@510
|
483 COMMENT ON COLUMN "unfiltered_initiative_for_notification"."new_draft" IS 'TRUE if a new draft exists (using the "draft_id" column of the "supporter" table in case of "supported" initiatives and the "last_draft_id" column of the "notification_initiative_sent" table in all other cases)';
|
jbe@510
|
484 COMMENT ON COLUMN "unfiltered_initiative_for_notification"."new_suggestion_count" IS 'Number of new suggestions (using the "last_suggestion_id" column of the "notification_initiative_sent" table while ignoring suggestions with an "opinion")';
|
jbe@510
|
485
|
jbe@492
|
486 CREATE VIEW "initiative_for_notification" AS
|
jbe@499
|
487 SELECT "unfiltered1".*
|
jbe@499
|
488 FROM "unfiltered_initiative_for_notification" "unfiltered1"
|
jbe@499
|
489 JOIN "initiative" AS "initiative1" ON
|
jbe@499
|
490 "initiative1"."id" = "unfiltered1"."initiative_id"
|
jbe@499
|
491 JOIN "issue" AS "issue1" ON "issue1"."id" = "initiative1"."issue_id"
|
jbe@492
|
492 WHERE EXISTS (
|
jbe@492
|
493 SELECT NULL
|
jbe@499
|
494 FROM "unfiltered_initiative_for_notification" "unfiltered2"
|
jbe@499
|
495 JOIN "initiative" AS "initiative2" ON
|
jbe@499
|
496 "initiative2"."id" = "unfiltered2"."initiative_id"
|
jbe@499
|
497 JOIN "issue" AS "issue2" ON "issue2"."id" = "initiative2"."issue_id"
|
jbe@499
|
498 WHERE "unfiltered1"."recipient_id" = "unfiltered2"."recipient_id"
|
jbe@492
|
499 AND "issue1"."area_id" = "issue2"."area_id"
|
jbe@499
|
500 AND ("unfiltered2"."new_draft" OR "unfiltered2"."new_suggestion_count" > 0 )
|
jbe@492
|
501 );
|
jbe@492
|
502
|
jbe@510
|
503 COMMENT ON VIEW "initiative_for_notification" IS 'Initiatives to be included in a scheduled notification mail';
|
jbe@510
|
504
|
jbe@510
|
505 COMMENT ON COLUMN "initiative_for_notification"."recipient_id" IS '"id" of the member who receives the notification mail';
|
jbe@510
|
506 COMMENT ON COLUMN "initiative_for_notification"."featured" IS 'TRUE if the initiative has been included because it was selected by the "featured_initiative" algorithm (see source of function "featured_initiative")';
|
jbe@510
|
507 COMMENT ON COLUMN "initiative_for_notification"."initiative_id" IS '"id" of the initiative to be included in the notification mail';
|
jbe@510
|
508 COMMENT ON COLUMN "initiative_for_notification"."leading" IS 'TRUE if the initiative has the highest "supporter_count" in the issue';
|
jbe@510
|
509 COMMENT ON COLUMN "initiative_for_notification"."supported" IS 'TRUE if initiative is supported by the recipient';
|
jbe@510
|
510 COMMENT ON COLUMN "initiative_for_notification"."new_draft" IS 'TRUE if a new draft exists (using the "draft_id" column of the "supporter" table in case of "supported" initiatives and the "last_draft_id" column of the "notification_initiative_sent" table in all other cases)';
|
jbe@510
|
511 COMMENT ON COLUMN "initiative_for_notification"."new_suggestion_count" IS 'Number of new suggestions (using the "last_suggestion_id" column of the "notification_initiative_sent" table while ignoring suggestions with an "opinion")';
|
jbe@510
|
512
|
jbe@504
|
513 CREATE VIEW "scheduled_notification_to_send" AS
|
jbe@505
|
514 SELECT * FROM (
|
jbe@505
|
515 SELECT
|
jbe@505
|
516 "id" AS "recipient_id",
|
jbe@505
|
517 now() - CASE WHEN "notification_dow" ISNULL THEN
|
jbe@505
|
518 ( "notification_sent"::DATE + CASE
|
jbe@505
|
519 WHEN EXTRACT(HOUR FROM "notification_sent") < "notification_hour"
|
jbe@505
|
520 THEN 0 ELSE 1 END
|
jbe@505
|
521 )::TIMESTAMP + '1 hour'::INTERVAL * "notification_hour"
|
jbe@505
|
522 ELSE
|
jbe@505
|
523 ( "notification_sent"::DATE +
|
jbe@505
|
524 ( 7 + "notification_dow" -
|
jbe@505
|
525 EXTRACT(DOW FROM
|
jbe@505
|
526 ( "notification_sent"::DATE + CASE
|
jbe@505
|
527 WHEN EXTRACT(HOUR FROM "notification_sent") < "notification_hour"
|
jbe@505
|
528 THEN 0 ELSE 1 END
|
jbe@505
|
529 )::TIMESTAMP + '1 hour'::INTERVAL * "notification_hour"
|
jbe@505
|
530 )::INTEGER
|
jbe@505
|
531 ) % 7 +
|
jbe@505
|
532 CASE
|
jbe@505
|
533 WHEN EXTRACT(HOUR FROM "notification_sent") < "notification_hour"
|
jbe@505
|
534 THEN 0 ELSE 1
|
jbe@505
|
535 END
|
jbe@505
|
536 )::TIMESTAMP + '1 hour'::INTERVAL * "notification_hour"
|
jbe@505
|
537 END AS "pending"
|
jbe@505
|
538 FROM (
|
jbe@505
|
539 SELECT
|
jbe@505
|
540 "id",
|
jbe@505
|
541 COALESCE("notification_sent", "activated") AS "notification_sent",
|
jbe@505
|
542 "notification_dow",
|
jbe@505
|
543 "notification_hour"
|
jbe@505
|
544 FROM "member"
|
jbe@505
|
545 WHERE "disable_notifications" = FALSE
|
jbe@505
|
546 AND "notification_hour" NOTNULL
|
jbe@505
|
547 ) AS "subquery1"
|
jbe@505
|
548 ) AS "subquery2"
|
jbe@505
|
549 WHERE "pending" > '0'::INTERVAL;
|
jbe@504
|
550
|
jbe@510
|
551 COMMENT ON VIEW "scheduled_notification_to_send" IS 'Set of members where a scheduled notification mail is pending';
|
jbe@510
|
552
|
jbe@510
|
553 COMMENT ON COLUMN "scheduled_notification_to_send"."recipient_id" IS '"id" of the member who needs to receive a notification mail';
|
jbe@510
|
554 COMMENT ON COLUMN "scheduled_notification_to_send"."pending" IS 'Duration for which the notification mail has already been pending';
|
jbe@510
|
555
|
jbe@497
|
556 CREATE VIEW "newsletter_to_send" AS
|
jbe@497
|
557 SELECT
|
jbe@499
|
558 "member"."id" AS "recipient_id",
|
jbe@514
|
559 "newsletter"."id" AS "newsletter_id",
|
jbe@514
|
560 "newsletter"."published"
|
jbe@497
|
561 FROM "newsletter" CROSS JOIN "member"
|
jbe@497
|
562 LEFT JOIN "privilege" ON
|
jbe@497
|
563 "privilege"."member_id" = "member"."id" AND
|
jbe@497
|
564 "privilege"."unit_id" = "newsletter"."unit_id" AND
|
jbe@497
|
565 "privilege"."voting_right" = TRUE
|
jbe@497
|
566 LEFT JOIN "subscription" ON
|
jbe@497
|
567 "subscription"."member_id" = "member"."id" AND
|
jbe@497
|
568 "subscription"."unit_id" = "newsletter"."unit_id"
|
jbe@498
|
569 WHERE "newsletter"."published" <= now()
|
jbe@497
|
570 AND "newsletter"."sent" ISNULL
|
jbe@497
|
571 AND "member"."locked" = FALSE
|
jbe@497
|
572 AND (
|
jbe@497
|
573 "member"."disable_notifications" = FALSE OR
|
jbe@497
|
574 "newsletter"."include_all_members" = TRUE )
|
jbe@497
|
575 AND (
|
jbe@497
|
576 "newsletter"."unit_id" ISNULL OR
|
jbe@497
|
577 "privilege"."member_id" NOTNULL OR
|
jbe@497
|
578 "subscription"."member_id" NOTNULL );
|
jbe@497
|
579
|
jbe@510
|
580 COMMENT ON VIEW "newsletter_to_send" IS 'List of "newsletter_id"s for each member that are due to be sent out';
|
jbe@514
|
581 COMMENT ON COLUMN "newsletter"."published" IS 'Timestamp when the newsletter was supposed to be sent out (can be used for ordering)';
|
jbe@510
|
582
|
jbe@510
|
583 CREATE OR REPLACE FUNCTION "require_transaction_isolation"()
|
jbe@510
|
584 RETURNS VOID
|
jbe@510
|
585 LANGUAGE 'plpgsql' VOLATILE AS $$
|
jbe@510
|
586 BEGIN
|
jbe@510
|
587 IF
|
jbe@510
|
588 current_setting('transaction_isolation') NOT IN
|
jbe@510
|
589 ('repeatable read', 'serializable')
|
jbe@510
|
590 THEN
|
jbe@510
|
591 RAISE EXCEPTION 'Insufficient transaction isolation level' USING
|
jbe@510
|
592 HINT = 'Consider using SET TRANSACTION ISOLATION LEVEL REPEATABLE READ.';
|
jbe@510
|
593 END IF;
|
jbe@510
|
594 RETURN;
|
jbe@510
|
595 END;
|
jbe@510
|
596 $$;
|
jbe@510
|
597
|
jbe@492
|
598 CREATE FUNCTION "get_initiatives_for_notification"
|
jbe@501
|
599 ( "recipient_id_p" "member"."id"%TYPE )
|
jbe@492
|
600 RETURNS SETOF "initiative_for_notification"
|
jbe@492
|
601 LANGUAGE 'plpgsql' VOLATILE AS $$
|
jbe@492
|
602 DECLARE
|
jbe@492
|
603 "result_row" "initiative_for_notification"%ROWTYPE;
|
jbe@492
|
604 "last_draft_id_v" "draft"."id"%TYPE;
|
jbe@492
|
605 "last_suggestion_id_v" "suggestion"."id"%TYPE;
|
jbe@492
|
606 BEGIN
|
jbe@492
|
607 PERFORM "require_transaction_isolation"();
|
jbe@501
|
608 PERFORM NULL FROM "member" WHERE "id" = "recipient_id_p" FOR UPDATE;
|
jbe@492
|
609 FOR "result_row" IN
|
jbe@492
|
610 SELECT * FROM "initiative_for_notification"
|
jbe@501
|
611 WHERE "recipient_id" = "recipient_id_p"
|
jbe@492
|
612 LOOP
|
jbe@492
|
613 SELECT "id" INTO "last_draft_id_v" FROM "draft"
|
jbe@499
|
614 WHERE "draft"."initiative_id" = "result_row"."initiative_id"
|
jbe@492
|
615 ORDER BY "id" DESC LIMIT 1;
|
jbe@492
|
616 SELECT "id" INTO "last_suggestion_id_v" FROM "suggestion"
|
jbe@499
|
617 WHERE "suggestion"."initiative_id" = "result_row"."initiative_id"
|
jbe@492
|
618 ORDER BY "id" DESC LIMIT 1;
|
jbe@517
|
619 /* compatibility with PostgreSQL 9.1 */
|
jbe@517
|
620 DELETE FROM "notification_initiative_sent"
|
jbe@517
|
621 WHERE "member_id" = "recipient_id_p"
|
jbe@517
|
622 AND "initiative_id" = "result_row"."initiative_id";
|
jbe@517
|
623 INSERT INTO "notification_initiative_sent"
|
jbe@517
|
624 ("member_id", "initiative_id", "last_draft_id", "last_suggestion_id")
|
jbe@517
|
625 VALUES (
|
jbe@517
|
626 "recipient_id_p",
|
jbe@517
|
627 "result_row"."initiative_id",
|
jbe@517
|
628 "last_draft_id_v",
|
jbe@517
|
629 "last_suggestion_id_v" );
|
jbe@517
|
630 /* TODO: use alternative code below, requires PostgreSQL 9.5 or higher
|
jbe@510
|
631 INSERT INTO "notification_initiative_sent"
|
jbe@492
|
632 ("member_id", "initiative_id", "last_draft_id", "last_suggestion_id")
|
jbe@492
|
633 VALUES (
|
jbe@501
|
634 "recipient_id_p",
|
jbe@499
|
635 "result_row"."initiative_id",
|
jbe@493
|
636 "last_draft_id_v",
|
jbe@493
|
637 "last_suggestion_id_v" )
|
jbe@492
|
638 ON CONFLICT ("member_id", "initiative_id") DO UPDATE SET
|
jbe@517
|
639 "last_draft_id" = "last_draft_id_v",
|
jbe@517
|
640 "last_suggestion_id" = "last_suggestion_id_v";
|
jbe@517
|
641 */
|
jbe@492
|
642 RETURN NEXT "result_row";
|
jbe@492
|
643 END LOOP;
|
jbe@510
|
644 DELETE FROM "notification_initiative_sent"
|
jbe@492
|
645 USING "initiative", "issue"
|
jbe@510
|
646 WHERE "notification_initiative_sent"."member_id" = "recipient_id_p"
|
jbe@510
|
647 AND "initiative"."id" = "notification_initiative_sent"."initiative_id"
|
jbe@492
|
648 AND "issue"."id" = "initiative"."issue_id"
|
jbe@492
|
649 AND ( "issue"."closed" NOTNULL OR "issue"."fully_frozen" NOTNULL );
|
jbe@505
|
650 UPDATE "member" SET
|
jbe@506
|
651 "notification_counter" = "notification_counter" + 1,
|
jbe@505
|
652 "notification_sent" = now()
|
jbe@501
|
653 WHERE "id" = "recipient_id_p";
|
jbe@492
|
654 RETURN;
|
jbe@492
|
655 END;
|
jbe@492
|
656 $$;
|
jbe@492
|
657
|
jbe@511
|
658 COMMENT ON FUNCTION "get_initiatives_for_notification"
|
jbe@511
|
659 ( "member"."id"%TYPE )
|
jbe@511
|
660 IS 'Returns rows from view "initiative_for_notification" for a given recipient while updating table "notification_initiative_sent" and columns "notification_counter" and "notification_sent" of "member" table';
|
jbe@510
|
661
|
jbe@510
|
662 CREATE OR REPLACE FUNCTION "delete_member"("member_id_p" "member"."id"%TYPE)
|
jbe@510
|
663 RETURNS VOID
|
jbe@510
|
664 LANGUAGE 'plpgsql' VOLATILE AS $$
|
jbe@510
|
665 BEGIN
|
jbe@510
|
666 UPDATE "member" SET
|
jbe@510
|
667 "last_login" = NULL,
|
jbe@510
|
668 "last_delegation_check" = NULL,
|
jbe@510
|
669 "login" = NULL,
|
jbe@510
|
670 "password" = NULL,
|
jbe@510
|
671 "authority" = NULL,
|
jbe@510
|
672 "authority_uid" = NULL,
|
jbe@510
|
673 "authority_login" = NULL,
|
jbe@510
|
674 "locked" = TRUE,
|
jbe@510
|
675 "active" = FALSE,
|
jbe@510
|
676 "notify_email" = NULL,
|
jbe@510
|
677 "notify_email_unconfirmed" = NULL,
|
jbe@510
|
678 "notify_email_secret" = NULL,
|
jbe@510
|
679 "notify_email_secret_expiry" = NULL,
|
jbe@510
|
680 "notify_email_lock_expiry" = NULL,
|
jbe@510
|
681 "disable_notifications" = NULL,
|
jbe@510
|
682 "notification_counter" = NULL,
|
jbe@510
|
683 "notification_sample_size" = NULL,
|
jbe@510
|
684 "notification_dow" = NULL,
|
jbe@510
|
685 "notification_hour" = NULL,
|
jbe@510
|
686 "login_recovery_expiry" = NULL,
|
jbe@510
|
687 "password_reset_secret" = NULL,
|
jbe@510
|
688 "password_reset_secret_expiry" = NULL,
|
jbe@510
|
689 "organizational_unit" = NULL,
|
jbe@510
|
690 "internal_posts" = NULL,
|
jbe@510
|
691 "realname" = NULL,
|
jbe@510
|
692 "birthday" = NULL,
|
jbe@510
|
693 "address" = NULL,
|
jbe@510
|
694 "email" = NULL,
|
jbe@510
|
695 "xmpp_address" = NULL,
|
jbe@510
|
696 "website" = NULL,
|
jbe@510
|
697 "phone" = NULL,
|
jbe@510
|
698 "mobile_phone" = NULL,
|
jbe@510
|
699 "profession" = NULL,
|
jbe@510
|
700 "external_memberships" = NULL,
|
jbe@510
|
701 "external_posts" = NULL,
|
jbe@510
|
702 "statement" = NULL
|
jbe@510
|
703 WHERE "id" = "member_id_p";
|
jbe@510
|
704 -- "text_search_data" is updated by triggers
|
jbe@510
|
705 DELETE FROM "setting" WHERE "member_id" = "member_id_p";
|
jbe@510
|
706 DELETE FROM "setting_map" WHERE "member_id" = "member_id_p";
|
jbe@510
|
707 DELETE FROM "member_relation_setting" WHERE "member_id" = "member_id_p";
|
jbe@510
|
708 DELETE FROM "member_image" WHERE "member_id" = "member_id_p";
|
jbe@510
|
709 DELETE FROM "contact" WHERE "member_id" = "member_id_p";
|
jbe@510
|
710 DELETE FROM "ignored_member" WHERE "member_id" = "member_id_p";
|
jbe@510
|
711 DELETE FROM "session" WHERE "member_id" = "member_id_p";
|
jbe@510
|
712 DELETE FROM "area_setting" WHERE "member_id" = "member_id_p";
|
jbe@510
|
713 DELETE FROM "issue_setting" WHERE "member_id" = "member_id_p";
|
jbe@510
|
714 DELETE FROM "ignored_initiative" WHERE "member_id" = "member_id_p";
|
jbe@510
|
715 DELETE FROM "initiative_setting" WHERE "member_id" = "member_id_p";
|
jbe@510
|
716 DELETE FROM "suggestion_setting" WHERE "member_id" = "member_id_p";
|
jbe@510
|
717 DELETE FROM "membership" WHERE "member_id" = "member_id_p";
|
jbe@510
|
718 DELETE FROM "delegation" WHERE "truster_id" = "member_id_p";
|
jbe@510
|
719 DELETE FROM "non_voter" WHERE "member_id" = "member_id_p";
|
jbe@510
|
720 DELETE FROM "direct_voter" USING "issue"
|
jbe@510
|
721 WHERE "direct_voter"."issue_id" = "issue"."id"
|
jbe@510
|
722 AND "issue"."closed" ISNULL
|
jbe@510
|
723 AND "member_id" = "member_id_p";
|
jbe@510
|
724 RETURN;
|
jbe@510
|
725 END;
|
jbe@510
|
726 $$;
|
jbe@510
|
727
|
jbe@510
|
728 CREATE OR REPLACE FUNCTION "delete_private_data"()
|
jbe@510
|
729 RETURNS VOID
|
jbe@510
|
730 LANGUAGE 'plpgsql' VOLATILE AS $$
|
jbe@510
|
731 BEGIN
|
jbe@510
|
732 DELETE FROM "temporary_transaction_data";
|
jbe@510
|
733 DELETE FROM "member" WHERE "activated" ISNULL;
|
jbe@510
|
734 UPDATE "member" SET
|
jbe@510
|
735 "invite_code" = NULL,
|
jbe@510
|
736 "invite_code_expiry" = NULL,
|
jbe@510
|
737 "admin_comment" = NULL,
|
jbe@510
|
738 "last_login" = NULL,
|
jbe@510
|
739 "last_delegation_check" = NULL,
|
jbe@510
|
740 "login" = NULL,
|
jbe@510
|
741 "password" = NULL,
|
jbe@510
|
742 "authority" = NULL,
|
jbe@510
|
743 "authority_uid" = NULL,
|
jbe@510
|
744 "authority_login" = NULL,
|
jbe@510
|
745 "lang" = NULL,
|
jbe@510
|
746 "notify_email" = NULL,
|
jbe@510
|
747 "notify_email_unconfirmed" = NULL,
|
jbe@510
|
748 "notify_email_secret" = NULL,
|
jbe@510
|
749 "notify_email_secret_expiry" = NULL,
|
jbe@510
|
750 "notify_email_lock_expiry" = NULL,
|
jbe@510
|
751 "disable_notifications" = NULL,
|
jbe@510
|
752 "notification_counter" = NULL,
|
jbe@510
|
753 "notification_sample_size" = NULL,
|
jbe@510
|
754 "notification_dow" = NULL,
|
jbe@510
|
755 "notification_hour" = NULL,
|
jbe@510
|
756 "login_recovery_expiry" = NULL,
|
jbe@510
|
757 "password_reset_secret" = NULL,
|
jbe@510
|
758 "password_reset_secret_expiry" = NULL,
|
jbe@510
|
759 "organizational_unit" = NULL,
|
jbe@510
|
760 "internal_posts" = NULL,
|
jbe@510
|
761 "realname" = NULL,
|
jbe@510
|
762 "birthday" = NULL,
|
jbe@510
|
763 "address" = NULL,
|
jbe@510
|
764 "email" = NULL,
|
jbe@510
|
765 "xmpp_address" = NULL,
|
jbe@510
|
766 "website" = NULL,
|
jbe@510
|
767 "phone" = NULL,
|
jbe@510
|
768 "mobile_phone" = NULL,
|
jbe@510
|
769 "profession" = NULL,
|
jbe@510
|
770 "external_memberships" = NULL,
|
jbe@510
|
771 "external_posts" = NULL,
|
jbe@510
|
772 "formatting_engine" = NULL,
|
jbe@510
|
773 "statement" = NULL;
|
jbe@510
|
774 -- "text_search_data" is updated by triggers
|
jbe@510
|
775 DELETE FROM "setting";
|
jbe@510
|
776 DELETE FROM "setting_map";
|
jbe@510
|
777 DELETE FROM "member_relation_setting";
|
jbe@510
|
778 DELETE FROM "member_image";
|
jbe@510
|
779 DELETE FROM "contact";
|
jbe@510
|
780 DELETE FROM "ignored_member";
|
jbe@510
|
781 DELETE FROM "session";
|
jbe@510
|
782 DELETE FROM "area_setting";
|
jbe@510
|
783 DELETE FROM "issue_setting";
|
jbe@510
|
784 DELETE FROM "ignored_initiative";
|
jbe@510
|
785 DELETE FROM "initiative_setting";
|
jbe@510
|
786 DELETE FROM "suggestion_setting";
|
jbe@510
|
787 DELETE FROM "non_voter";
|
jbe@510
|
788 DELETE FROM "direct_voter" USING "issue"
|
jbe@510
|
789 WHERE "direct_voter"."issue_id" = "issue"."id"
|
jbe@510
|
790 AND "issue"."closed" ISNULL;
|
jbe@510
|
791 RETURN;
|
jbe@510
|
792 END;
|
jbe@510
|
793 $$;
|
jbe@510
|
794
|
jbe@478
|
795 COMMIT;
|