liquid_feedback_core

annotate update/core-update.v2.0.11-v2.1.0.sql @ 291:86f231bd6906

Issues may have an admission_time set to NULL
author jbe
date Mon Aug 20 03:28:45 2012 +0200 (2012-08-20)
parents 2301a1f2acfa
children 3de42ea02dc2
rev   line source
jbe@262 1 BEGIN;
jbe@262 2
jbe@287 3
jbe@287 4 -- update version number
jbe@287 5
jbe@262 6 CREATE OR REPLACE VIEW "liquid_feedback_version" AS
jbe@262 7 SELECT * FROM (VALUES ('2.1.0', 2, 1, 0))
jbe@262 8 AS "subquery"("string", "major", "minor", "revision");
jbe@262 9
jbe@287 10
jbe@287 11 -- old API tables are now deprecated
jbe@287 12
jbe@286 13 COMMENT ON TYPE "application_access_level" IS 'DEPRECATED, WILL BE REMOVED! Access privileges for applications using the API';
jbe@286 14 COMMENT ON TABLE "member_application" IS 'DEPRECATED, WILL BE REMOVED! Registered application being allowed to use the API';
jbe@286 15
jbe@287 16
jbe@287 17 -- new polling mode and changed privileges
jbe@287 18
jbe@262 19 ALTER TABLE "policy" ADD COLUMN "polling" BOOLEAN NOT NULL DEFAULT FALSE;
jbe@262 20 ALTER TABLE "policy" ALTER COLUMN "admission_time" DROP NOT NULL;
jbe@262 21 ALTER TABLE "policy" ALTER COLUMN "discussion_time" DROP NOT NULL;
jbe@262 22 ALTER TABLE "policy" ALTER COLUMN "verification_time" DROP NOT NULL;
jbe@262 23 ALTER TABLE "policy" ALTER COLUMN "voting_time" DROP NOT NULL;
jbe@262 24 ALTER TABLE "policy" ADD CONSTRAINT "timing" CHECK (
jbe@262 25 ( "polling" = FALSE AND
jbe@262 26 "admission_time" NOTNULL AND "discussion_time" NOTNULL AND
jbe@262 27 "verification_time" NOTNULL AND "voting_time" NOTNULL ) OR
jbe@262 28 ( "polling" = TRUE AND
jbe@263 29 "admission_time" ISNULL AND "discussion_time" NOTNULL AND
jbe@262 30 "verification_time" NOTNULL AND "voting_time" NOTNULL ) OR
jbe@262 31 ( "polling" = TRUE AND
jbe@262 32 "admission_time" ISNULL AND "discussion_time" ISNULL AND
jbe@262 33 "verification_time" ISNULL AND "voting_time" ISNULL ) );
jbe@289 34 COMMENT ON COLUMN "policy"."polling" IS 'TRUE = special policy for non-user-generated issues without issue quorum, where certain initiatives (those having the "polling" flag set) do not need to pass the initiative quorum; "admission_time" MUST be set to NULL, the other timings may be set to NULL altogether, allowing individual timing for those issues';
jbe@262 35
jbe@291 36 ALTER TABLE "issue" ALTER COLUMN "admission_time" DROP NOT NULL;
jbe@291 37 ALTER TABLE "issue" ADD CONSTRAINT "admission_time_not_null_unless_instantly_accepted" CHECK (
jbe@291 38 "admission_time" NOTNULL OR ("accepted" NOTNULL AND "accepted" = "created") );
jbe@291 39
jbe@262 40 ALTER TABLE "initiative" ADD COLUMN "polling" BOOLEAN NOT NULL DEFAULT FALSE;
jbe@289 41 COMMENT ON COLUMN "initiative"."polling" IS 'Initiative does not need to pass the initiative quorum (see "policy"."polling")';
jbe@262 42
jbe@262 43 ALTER TABLE "privilege" RENAME COLUMN "voting_right_manager" TO "member_manager";
jbe@262 44 ALTER TABLE "privilege" ADD COLUMN "initiative_right" BOOLEAN NOT NULL DEFAULT TRUE;
jbe@262 45 ALTER TABLE "privilege" ADD COLUMN "polling_right" BOOLEAN NOT NULL DEFAULT FALSE;
jbe@262 46 UPDATE "privilege" SET "initiative_right" = "voting_right";
jbe@262 47 COMMENT ON COLUMN "privilege"."admin_manager" IS 'Grant/revoke any privileges to/from other members';
jbe@262 48 COMMENT ON COLUMN "privilege"."member_manager" IS 'Adding/removing members from the unit, granting or revoking "initiative_right" and "voting_right"';
jbe@262 49 COMMENT ON COLUMN "privilege"."initiative_right" IS 'Right to create an initiative';
jbe@262 50 COMMENT ON COLUMN "privilege"."voting_right" IS 'Right to support initiatives, create and rate suggestions, and to vote';
jbe@289 51 COMMENT ON COLUMN "privilege"."polling_right" IS 'Right to create issues with policies having the "policy"."polling" flag set, and to add initiatives having the "initiative"."polling" flag set to those issues';
jbe@262 52
jbe@262 53 CREATE OR REPLACE FUNCTION "freeze_after_snapshot"
jbe@262 54 ( "issue_id_p" "issue"."id"%TYPE )
jbe@262 55 RETURNS VOID
jbe@262 56 LANGUAGE 'plpgsql' VOLATILE AS $$
jbe@262 57 DECLARE
jbe@262 58 "issue_row" "issue"%ROWTYPE;
jbe@262 59 "policy_row" "policy"%ROWTYPE;
jbe@262 60 "initiative_row" "initiative"%ROWTYPE;
jbe@262 61 BEGIN
jbe@262 62 SELECT * INTO "issue_row" FROM "issue" WHERE "id" = "issue_id_p";
jbe@262 63 SELECT * INTO "policy_row"
jbe@262 64 FROM "policy" WHERE "id" = "issue_row"."policy_id";
jbe@262 65 PERFORM "set_snapshot_event"("issue_id_p", 'full_freeze');
jbe@262 66 FOR "initiative_row" IN
jbe@262 67 SELECT * FROM "initiative"
jbe@262 68 WHERE "issue_id" = "issue_id_p" AND "revoked" ISNULL
jbe@262 69 LOOP
jbe@262 70 IF
jbe@262 71 "initiative_row"."polling" OR (
jbe@262 72 "initiative_row"."satisfied_supporter_count" > 0 AND
jbe@262 73 "initiative_row"."satisfied_supporter_count" *
jbe@262 74 "policy_row"."initiative_quorum_den" >=
jbe@262 75 "issue_row"."population" * "policy_row"."initiative_quorum_num"
jbe@262 76 )
jbe@262 77 THEN
jbe@262 78 UPDATE "initiative" SET "admitted" = TRUE
jbe@262 79 WHERE "id" = "initiative_row"."id";
jbe@262 80 ELSE
jbe@262 81 UPDATE "initiative" SET "admitted" = FALSE
jbe@262 82 WHERE "id" = "initiative_row"."id";
jbe@262 83 END IF;
jbe@262 84 END LOOP;
jbe@262 85 IF EXISTS (
jbe@262 86 SELECT NULL FROM "initiative"
jbe@262 87 WHERE "issue_id" = "issue_id_p" AND "admitted" = TRUE
jbe@262 88 ) THEN
jbe@262 89 UPDATE "issue" SET
jbe@262 90 "state" = 'voting',
jbe@262 91 "accepted" = coalesce("accepted", now()),
jbe@262 92 "half_frozen" = coalesce("half_frozen", now()),
jbe@262 93 "fully_frozen" = now()
jbe@262 94 WHERE "id" = "issue_id_p";
jbe@262 95 ELSE
jbe@262 96 UPDATE "issue" SET
jbe@262 97 "state" = 'canceled_no_initiative_admitted',
jbe@262 98 "accepted" = coalesce("accepted", now()),
jbe@262 99 "half_frozen" = coalesce("half_frozen", now()),
jbe@262 100 "fully_frozen" = now(),
jbe@262 101 "closed" = now(),
jbe@262 102 "ranks_available" = TRUE
jbe@262 103 WHERE "id" = "issue_id_p";
jbe@262 104 -- NOTE: The following DELETE statements have effect only when
jbe@262 105 -- issue state has been manipulated
jbe@262 106 DELETE FROM "direct_voter" WHERE "issue_id" = "issue_id_p";
jbe@262 107 DELETE FROM "delegating_voter" WHERE "issue_id" = "issue_id_p";
jbe@262 108 DELETE FROM "battle" WHERE "issue_id" = "issue_id_p";
jbe@262 109 END IF;
jbe@262 110 RETURN;
jbe@262 111 END;
jbe@262 112 $$;
jbe@262 113
jbe@287 114
jbe@287 115 -- issue comments removed, voting comments integrated in "direct_voter" table
jbe@287 116
jbe@287 117 ALTER TABLE "direct_voter" ADD COLUMN "comment_changed" TIMESTAMPTZ;
jbe@287 118 ALTER TABLE "direct_voter" ADD COLUMN "formatting_engine" TEXT;
jbe@287 119 ALTER TABLE "direct_voter" ADD COLUMN "comment" TEXT;
jbe@287 120 ALTER TABLE "direct_voter" ADD COLUMN "text_search_data" TSVECTOR;
jbe@287 121 CREATE INDEX "direct_voter_text_search_data_idx" ON "direct_voter" USING gin ("text_search_data");
jbe@287 122 CREATE TRIGGER "update_text_search_data"
jbe@287 123 BEFORE INSERT OR UPDATE ON "direct_voter"
jbe@287 124 FOR EACH ROW EXECUTE PROCEDURE
jbe@287 125 tsvector_update_trigger('text_search_data', 'pg_catalog.simple', "comment");
jbe@287 126
jbe@287 127 COMMENT ON COLUMN "direct_voter"."comment_changed" IS 'Shall be set on comment change, to indicate a comment being modified after voting has been finished; Automatically set to NULL after voting phase; Automatically set to NULL by trigger, if "comment" is set to NULL';
jbe@287 128 COMMENT ON COLUMN "direct_voter"."formatting_engine" IS 'Allows different formatting engines (i.e. wiki formats) to be used for "direct_voter"."comment"; Automatically set to NULL by trigger, if "comment" is set to NULL';
jbe@287 129 COMMENT ON COLUMN "direct_voter"."comment" IS 'Is to be set or updated by the frontend, if comment was inserted or updated AFTER the issue has been closed. Otherwise it shall be set to NULL.';
jbe@287 130
jbe@287 131 CREATE TABLE "rendered_voter_comment" (
jbe@287 132 PRIMARY KEY ("issue_id", "member_id", "format"),
jbe@287 133 FOREIGN KEY ("issue_id", "member_id")
jbe@287 134 REFERENCES "direct_voter" ("issue_id", "member_id")
jbe@287 135 ON DELETE CASCADE ON UPDATE CASCADE,
jbe@287 136 "issue_id" INT4,
jbe@287 137 "member_id" INT4,
jbe@287 138 "format" TEXT,
jbe@287 139 "content" TEXT NOT NULL );
jbe@287 140
jbe@287 141 COMMENT ON TABLE "rendered_voter_comment" IS 'This table may be used by frontends to cache "rendered" voter comments (e.g. HTML output generated from wiki text)';
jbe@287 142
jbe@287 143 DROP TABLE "rendered_issue_comment";
jbe@287 144 DROP TABLE "issue_comment";
jbe@287 145 DROP TABLE "rendered_voting_comment";
jbe@287 146 DROP TABLE "voting_comment";
jbe@287 147
jbe@287 148 CREATE FUNCTION "voter_comment_fields_only_set_when_voter_comment_is_set_trigger"()
jbe@287 149 RETURNS TRIGGER
jbe@287 150 LANGUAGE 'plpgsql' VOLATILE AS $$
jbe@287 151 BEGIN
jbe@287 152 IF NEW."comment" ISNULL THEN
jbe@287 153 NEW."comment_changed" := NULL;
jbe@287 154 NEW."formatting_engine" := NULL;
jbe@287 155 END IF;
jbe@287 156 RETURN NEW;
jbe@287 157 END;
jbe@287 158 $$;
jbe@287 159
jbe@287 160 CREATE TRIGGER "voter_comment_fields_only_set_when_voter_comment_is_set"
jbe@287 161 BEFORE INSERT OR UPDATE ON "direct_voter"
jbe@287 162 FOR EACH ROW EXECUTE PROCEDURE
jbe@287 163 "voter_comment_fields_only_set_when_voter_comment_is_set_trigger"();
jbe@287 164
jbe@287 165 COMMENT ON FUNCTION "voter_comment_fields_only_set_when_voter_comment_is_set_trigger"() IS 'Implementation of trigger "voter_comment_fields_only_set_when_voter_comment_is_set" ON table "direct_voter"';
jbe@287 166 COMMENT ON TRIGGER "voter_comment_fields_only_set_when_voter_comment_is_set" ON "direct_voter" IS 'If "comment" is set to NULL, then other comment related fields are also set to NULL.';
jbe@287 167
jbe@290 168 CREATE OR REPLACE FUNCTION "forbid_changes_on_closed_issue_trigger"()
jbe@290 169 RETURNS TRIGGER
jbe@290 170 LANGUAGE 'plpgsql' VOLATILE AS $$
jbe@290 171 DECLARE
jbe@290 172 "issue_id_v" "issue"."id"%TYPE;
jbe@290 173 "issue_row" "issue"%ROWTYPE;
jbe@290 174 BEGIN
jbe@290 175 IF TG_RELID = 'direct_voter'::regclass AND TG_OP = 'UPDATE' THEN
jbe@290 176 IF
jbe@290 177 OLD."issue_id" = NEW."issue_id" AND
jbe@290 178 OLD."member_id" = NEW."member_id" AND
jbe@290 179 OLD."weight" = NEW."weight"
jbe@290 180 THEN
jbe@290 181 RETURN NULL; -- allows changing of voter comment
jbe@290 182 END IF;
jbe@290 183 END IF;
jbe@290 184 IF TG_OP = 'DELETE' THEN
jbe@290 185 "issue_id_v" := OLD."issue_id";
jbe@290 186 ELSE
jbe@290 187 "issue_id_v" := NEW."issue_id";
jbe@290 188 END IF;
jbe@290 189 SELECT INTO "issue_row" * FROM "issue"
jbe@290 190 WHERE "id" = "issue_id_v" FOR SHARE;
jbe@290 191 IF "issue_row"."closed" NOTNULL THEN
jbe@290 192 RAISE EXCEPTION 'Tried to modify data belonging to a closed issue.';
jbe@290 193 END IF;
jbe@290 194 RETURN NULL;
jbe@290 195 END;
jbe@290 196 $$;
jbe@290 197
jbe@285 198 CREATE OR REPLACE FUNCTION "close_voting"("issue_id_p" "issue"."id"%TYPE)
jbe@285 199 RETURNS VOID
jbe@285 200 LANGUAGE 'plpgsql' VOLATILE AS $$
jbe@285 201 DECLARE
jbe@285 202 "area_id_v" "area"."id"%TYPE;
jbe@285 203 "unit_id_v" "unit"."id"%TYPE;
jbe@285 204 "member_id_v" "member"."id"%TYPE;
jbe@285 205 BEGIN
jbe@285 206 PERFORM "lock_issue"("issue_id_p");
jbe@285 207 SELECT "area_id" INTO "area_id_v" FROM "issue" WHERE "id" = "issue_id_p";
jbe@285 208 SELECT "unit_id" INTO "unit_id_v" FROM "area" WHERE "id" = "area_id_v";
jbe@285 209 -- delete timestamp of voting comment:
jbe@285 210 UPDATE "direct_voter" SET "comment_changed" = NULL
jbe@285 211 WHERE "issue_id" = "issue_id_p";
jbe@285 212 -- delete delegating votes (in cases of manual reset of issue state):
jbe@285 213 DELETE FROM "delegating_voter"
jbe@285 214 WHERE "issue_id" = "issue_id_p";
jbe@285 215 -- delete votes from non-privileged voters:
jbe@285 216 DELETE FROM "direct_voter"
jbe@285 217 USING (
jbe@285 218 SELECT
jbe@285 219 "direct_voter"."member_id"
jbe@285 220 FROM "direct_voter"
jbe@285 221 JOIN "member" ON "direct_voter"."member_id" = "member"."id"
jbe@285 222 LEFT JOIN "privilege"
jbe@285 223 ON "privilege"."unit_id" = "unit_id_v"
jbe@285 224 AND "privilege"."member_id" = "direct_voter"."member_id"
jbe@285 225 WHERE "direct_voter"."issue_id" = "issue_id_p" AND (
jbe@285 226 "member"."active" = FALSE OR
jbe@285 227 "privilege"."voting_right" ISNULL OR
jbe@285 228 "privilege"."voting_right" = FALSE
jbe@285 229 )
jbe@285 230 ) AS "subquery"
jbe@285 231 WHERE "direct_voter"."issue_id" = "issue_id_p"
jbe@285 232 AND "direct_voter"."member_id" = "subquery"."member_id";
jbe@285 233 -- consider delegations:
jbe@285 234 UPDATE "direct_voter" SET "weight" = 1
jbe@285 235 WHERE "issue_id" = "issue_id_p";
jbe@285 236 PERFORM "add_vote_delegations"("issue_id_p");
jbe@285 237 -- set voter count and mark issue as being calculated:
jbe@285 238 UPDATE "issue" SET
jbe@285 239 "state" = 'calculation',
jbe@285 240 "closed" = now(),
jbe@285 241 "voter_count" = (
jbe@285 242 SELECT coalesce(sum("weight"), 0)
jbe@285 243 FROM "direct_voter" WHERE "issue_id" = "issue_id_p"
jbe@285 244 )
jbe@285 245 WHERE "id" = "issue_id_p";
jbe@285 246 -- materialize battle_view:
jbe@285 247 -- NOTE: "closed" column of issue must be set at this point
jbe@285 248 DELETE FROM "battle" WHERE "issue_id" = "issue_id_p";
jbe@285 249 INSERT INTO "battle" (
jbe@285 250 "issue_id",
jbe@285 251 "winning_initiative_id", "losing_initiative_id",
jbe@285 252 "count"
jbe@285 253 ) SELECT
jbe@285 254 "issue_id",
jbe@285 255 "winning_initiative_id", "losing_initiative_id",
jbe@285 256 "count"
jbe@285 257 FROM "battle_view" WHERE "issue_id" = "issue_id_p";
jbe@285 258 -- copy "positive_votes" and "negative_votes" from "battle" table:
jbe@285 259 UPDATE "initiative" SET
jbe@285 260 "positive_votes" = "battle_win"."count",
jbe@285 261 "negative_votes" = "battle_lose"."count"
jbe@285 262 FROM "battle" AS "battle_win", "battle" AS "battle_lose"
jbe@285 263 WHERE
jbe@285 264 "battle_win"."issue_id" = "issue_id_p" AND
jbe@285 265 "battle_win"."winning_initiative_id" = "initiative"."id" AND
jbe@285 266 "battle_win"."losing_initiative_id" ISNULL AND
jbe@285 267 "battle_lose"."issue_id" = "issue_id_p" AND
jbe@285 268 "battle_lose"."losing_initiative_id" = "initiative"."id" AND
jbe@285 269 "battle_lose"."winning_initiative_id" ISNULL;
jbe@285 270 END;
jbe@285 271 $$;
jbe@285 272
jbe@288 273 CREATE OR REPLACE FUNCTION "clean_issue"("issue_id_p" "issue"."id"%TYPE)
jbe@288 274 RETURNS VOID
jbe@288 275 LANGUAGE 'plpgsql' VOLATILE AS $$
jbe@288 276 DECLARE
jbe@288 277 "issue_row" "issue"%ROWTYPE;
jbe@288 278 BEGIN
jbe@288 279 SELECT * INTO "issue_row"
jbe@288 280 FROM "issue" WHERE "id" = "issue_id_p"
jbe@288 281 FOR UPDATE;
jbe@288 282 IF "issue_row"."cleaned" ISNULL THEN
jbe@288 283 UPDATE "issue" SET
jbe@288 284 "state" = 'voting',
jbe@288 285 "closed" = NULL,
jbe@288 286 "ranks_available" = FALSE
jbe@288 287 WHERE "id" = "issue_id_p";
jbe@288 288 DELETE FROM "delegating_voter"
jbe@288 289 WHERE "issue_id" = "issue_id_p";
jbe@288 290 DELETE FROM "direct_voter"
jbe@288 291 WHERE "issue_id" = "issue_id_p";
jbe@288 292 DELETE FROM "delegating_interest_snapshot"
jbe@288 293 WHERE "issue_id" = "issue_id_p";
jbe@288 294 DELETE FROM "direct_interest_snapshot"
jbe@288 295 WHERE "issue_id" = "issue_id_p";
jbe@288 296 DELETE FROM "delegating_population_snapshot"
jbe@288 297 WHERE "issue_id" = "issue_id_p";
jbe@288 298 DELETE FROM "direct_population_snapshot"
jbe@288 299 WHERE "issue_id" = "issue_id_p";
jbe@288 300 DELETE FROM "non_voter"
jbe@288 301 WHERE "issue_id" = "issue_id_p";
jbe@288 302 DELETE FROM "delegation"
jbe@288 303 WHERE "issue_id" = "issue_id_p";
jbe@288 304 DELETE FROM "supporter"
jbe@288 305 WHERE "issue_id" = "issue_id_p";
jbe@288 306 UPDATE "issue" SET
jbe@288 307 "state" = "issue_row"."state",
jbe@288 308 "closed" = "issue_row"."closed",
jbe@288 309 "ranks_available" = "issue_row"."ranks_available",
jbe@288 310 "cleaned" = now()
jbe@288 311 WHERE "id" = "issue_id_p";
jbe@288 312 END IF;
jbe@288 313 RETURN;
jbe@288 314 END;
jbe@288 315 $$;
jbe@288 316
jbe@287 317
jbe@287 318 -- "non_voter" deletes "direct_voter" and vice versa
jbe@287 319
jbe@287 320 CREATE FUNCTION "non_voter_deletes_direct_voter_trigger"()
jbe@287 321 RETURNS TRIGGER
jbe@287 322 LANGUAGE 'plpgsql' VOLATILE AS $$
jbe@287 323 BEGIN
jbe@287 324 DELETE FROM "direct_voter"
jbe@287 325 WHERE "issue_id" = NEW."issue_id" AND "member_id" = NEW."member_id";
jbe@287 326 RETURN NULL;
jbe@287 327 END;
jbe@287 328 $$;
jbe@287 329
jbe@287 330 CREATE TRIGGER "non_voter_deletes_direct_voter"
jbe@287 331 AFTER INSERT OR UPDATE ON "non_voter"
jbe@287 332 FOR EACH ROW EXECUTE PROCEDURE
jbe@287 333 "non_voter_deletes_direct_voter_trigger"();
jbe@287 334
jbe@287 335 COMMENT ON FUNCTION "non_voter_deletes_direct_voter_trigger"() IS 'Implementation of trigger "non_voter_deletes_direct_voter" on table "non_voter"';
jbe@287 336 COMMENT ON TRIGGER "non_voter_deletes_direct_voter" ON "non_voter" IS 'An entry in the "non_voter" table deletes an entry in the "direct_voter" table (and vice versa due to trigger "direct_voter_deletes_non_voter" on table "direct_voter")';
jbe@287 337
jbe@287 338 CREATE FUNCTION "direct_voter_deletes_non_voter_trigger"()
jbe@287 339 RETURNS TRIGGER
jbe@287 340 LANGUAGE 'plpgsql' VOLATILE AS $$
jbe@287 341 BEGIN
jbe@287 342 DELETE FROM "non_voter"
jbe@287 343 WHERE "issue_id" = NEW."issue_id" AND "member_id" = NEW."member_id";
jbe@287 344 RETURN NULL;
jbe@287 345 END;
jbe@287 346 $$;
jbe@287 347
jbe@287 348 CREATE TRIGGER "direct_voter_deletes_non_voter"
jbe@287 349 AFTER INSERT OR UPDATE ON "direct_voter"
jbe@287 350 FOR EACH ROW EXECUTE PROCEDURE
jbe@287 351 "direct_voter_deletes_non_voter_trigger"();
jbe@287 352
jbe@287 353 COMMENT ON FUNCTION "direct_voter_deletes_non_voter_trigger"() IS 'Implementation of trigger "direct_voter_deletes_non_voter" on table "direct_voter"';
jbe@287 354 COMMENT ON TRIGGER "direct_voter_deletes_non_voter" ON "direct_voter" IS 'An entry in the "direct_voter" table deletes an entry in the "non_voter" table (and vice versa due to trigger "non_voter_deletes_direct_voter" on table "non_voter")';
jbe@287 355
jbe@287 356
jbe@287 357 -- new comment on function "delete_private_data"()
jbe@287 358
jbe@283 359 COMMENT ON FUNCTION "delete_private_data"() IS 'Used by lf_export script. DO NOT USE on productive database, but only on a copy! This function deletes all data which should not be publicly available, and can be used to create a database dump for publication. See source code to see which data is deleted. If you need a different behaviour, copy this function and modify lf_export accordingly, to avoid data-leaks after updating.';
jbe@283 360
jbe@287 361
jbe@262 362 COMMIT;

Impressum / About Us