Projekt

Allgemein

Profil

« Zurück | Weiter » 

Revision 6aa0427f

Von Moritz Bunkus vor mehr als 10 Jahren hinzugefügt

  • ID 6aa0427f24b81337089f4706fda5661b166b8268
  • Vorgänger d9ddb4ea
  • Nachfolger 5a469687

Pflichtenhefttrigger: rekursives Löschen darf kein UPDATE auf zu löschende Elemente ausführen

Weil PostgreSQL das momentan nicht kann. Hat man einen BEFORE
DELETE-Trigger, der (auch über Umwege) ein UPDATE auf diejenige Zeile
macht, die im BEFORE DELETE gelöscht werden soll, so kommt PostgreSQL
mit seinen internen Zeilenversionsnummern durcheinander, sodass die
Zeile dann letztlich nicht gelöscht wird.

Unterschiede anzeigen:

sql/Pg-upgrade2/requirement_specs.sql
247 247
ALTER TABLE customer ADD COLUMN hourly_rate NUMERIC(8, 2);
248 248

  
249 249

  
250
CREATE TABLE trigger_information (
251
       id    SERIAL PRIMARY KEY,
252
       key   TEXT   NOT NULL,
253
       value TEXT,
254

  
255
       UNIQUE (key, value)
256
);
257

  
250 258
-- Trigger for updating time_estimation of function blocks from their
251 259
-- children (not for sections, not for sub function blocks).
252 260
CREATE OR REPLACE FUNCTION update_requirement_spec_item_time_estimation(item_id INTEGER) RETURNS BOOLEAN AS $$
253 261
  DECLARE
254
    item   RECORD;
255
    parent RECORD;
262
    item RECORD;
256 263
  BEGIN
257 264
    IF item_id IS NULL THEN
258 265
      RAISE DEBUG 'updateRSIE: item_id IS NULL';
259 266
      RETURN FALSE;
260 267
    END IF;
261 268

  
262
    SELECT * INTO item FROM requirement_spec_items WHERE id = item_id;
263
    RAISE DEBUG 'updateRSIE: item_id % parent_id %', item_id, item.parent_id;
264

  
265
    IF item.parent_id IS NULL THEN
266
      -- Don't do anything for sections.
267
      RAISE DEBUG 'updateRSIE: this is a section.';
269
    IF EXISTS(
270
      SELECT *
271
      FROM trigger_information
272
      WHERE (key   = 'deleting_requirement_spec_item')
273
        AND (value = CAST(item_id AS TEXT))
274
      LIMIT 1
275
    ) THEN
276
      RAISE DEBUG 'updateRSIE: item_id % is about to be deleted; do not update', item_id;
268 277
      RETURN FALSE;
269 278
    END IF;
270 279

  
271
    SELECT * INTO parent FROM requirement_spec_items WHERE id = item.parent_id;
272
    RAISE DEBUG 'updateRSIE: parent_id of parent of item: %', parent.parent_id;
280
    SELECT * INTO item FROM requirement_spec_items WHERE id = item_id;
281
    RAISE DEBUG 'updateRSIE: item_id % item_type %', item_id, item.item_type;
273 282

  
274
    IF parent.parent_id IS NOT NULL THEN
275
      -- Don't do anything for sub function blocks.
276
      RAISE DEBUG 'updateRSIE: this is sub function block.';
283
    IF (item.item_type = 'section') OR (item.item_type = 'sub-function-block') THEN
284
      -- Don't do anything for sections and sub-function-blocks.
285
      RAISE DEBUG 'updateRSIE: this is a section/sub-function-block, not updating.';
277 286
      RETURN FALSE;
278 287
    END IF;
279 288

  
......
292 301
$$ LANGUAGE plpgsql;
293 302

  
294 303
CREATE OR REPLACE FUNCTION requirement_spec_item_time_estimation_updater_trigger() RETURNS trigger AS $$
304
  DECLARE
305
    do_new BOOLEAN;
295 306
  BEGIN
307
    RAISE DEBUG 'updateRSITE op %', TG_OP;
296 308
    IF ((TG_OP = 'UPDATE') OR (TG_OP = 'DELETE')) THEN
309
      RAISE DEBUG 'UPDATE trigg op % OLD.id % OLD.parent_id %', TG_OP, OLD.id, OLD.parent_id;
297 310
      PERFORM update_requirement_spec_item_time_estimation(OLD.parent_id);
311
      RAISE DEBUG 'UPDATE trigg op % END %', TG_OP, OLD.id;
312
    END IF;
313
    do_new = FALSE;
314

  
315
    IF (TG_OP = 'UPDATE') THEN
316
      do_new = OLD.parent_id <> NEW.parent_id;
298 317
    END IF;
299
    IF ((TG_OP = 'UPDATE') OR (TG_OP = 'INSERT')) THEN
318

  
319
    IF (do_new OR (TG_OP = 'INSERT')) THEN
320
      RAISE DEBUG 'UPDATE trigg op % NEW.id % NEW.parent_id %', TG_OP, NEW.id, NEW.parent_id;
300 321
      PERFORM update_requirement_spec_item_time_estimation(NEW.parent_id);
322
      RAISE DEBUG 'UPDATE trigg op % END %', TG_OP, NEW.id;
301 323
    END IF;
324

  
302 325
    RETURN NULL;
303 326
  END;
304 327
$$ LANGUAGE plpgsql;
......
313 336
CREATE OR REPLACE FUNCTION requirement_spec_item_before_delete_trigger() RETURNS trigger AS $$
314 337
  BEGIN
315 338
    RAISE DEBUG 'delete trig RSitem old id %', OLD.id;
339
    INSERT INTO trigger_information (key, value) VALUES ('deleting_requirement_spec_item', CAST(OLD.id AS TEXT));
316 340
    DELETE FROM requirement_spec_item_dependencies WHERE (depending_item_id = OLD.id) OR (depended_item_id = OLD.id);
317 341
    DELETE FROM requirement_spec_items             WHERE (parent_id         = OLD.id);
318

  
342
    DELETE FROM trigger_information                WHERE (key = 'deleting_requirement_spec_item') AND (value = CAST(OLD.id AS TEXT));
343
    RAISE DEBUG 'delete trig END %', OLD.id;
319 344
    RETURN OLD;
320 345
  END;
321 346
$$ LANGUAGE plpgsql;

Auch abrufbar als: Unified diff