~launchpad-results/launchpad-results/trunk

« back to all changes in this revision

Viewing changes to lib/lpresults/tracker/schema/test/__init__.py

  • Committer: Marc Tardif
  • Date: 2012-03-21 22:32:04 UTC
  • Revision ID: marc.tardif@canonical.com-20120321223204-8g7mvzzwmh8ifbrt
Added support for getting systems from a person (LP #899361)

Show diffs side-by-side

added added

removed removed

Lines of Context:
16
16
 
17
17
CREATES = [
18
18
"""
19
 
GRANT SELECT
 
19
GRANT SELECT, INSERT
20
20
    ON TABLE patch
21
21
    TO lpresults
22
22
""",
198
198
        date_deleted)
199
199
""",
200
200
"""
201
 
CREATE LANGUAGE plpgsql
 
201
CREATE OR REPLACE LANGUAGE plpgsql
202
202
""",
203
203
"""
204
204
CREATE FUNCTION get_test_case(
212
212
    test_case_id INTEGER;
213
213
BEGIN
214
214
    LOOP
215
 
        SELECT testcase.id INTO test_case_id FROM testcase
 
215
        SELECT testcase.id
 
216
            INTO test_case_id
 
217
            FROM testcase
216
218
            WHERE testcase.distro_series
217
219
                IS NOT DISTINCT FROM test_distro_series
218
220
            AND testcase.project_series
283
285
    TO lpresults
284
286
""",
285
287
"""
286
 
CREATE FUNCTION next_distroseries_sequence(
287
 
    distro_series INTEGER)
288
 
    RETURNS INTEGER
289
 
LANGUAGE plpgsql AS
290
 
$$
291
 
DECLARE
292
 
    next_sequence INTEGER;
293
 
BEGIN
294
 
    UPDATE distroseriestwin SET counter = counter + 1
295
 
        WHERE id = distro_series;
296
 
    SELECT INTO next_sequence counter FROM distroseriestwin
297
 
        WHERE id = distro_series;
298
 
    RETURN next_sequence;
299
 
END;
300
 
$$
301
 
""",
302
 
"""
303
 
GRANT EXECUTE
304
 
    ON FUNCTION next_distroseries_sequence(INTEGER)
305
 
    TO lpresults
306
 
""",
307
 
"""
308
 
CREATE FUNCTION next_projectseries_sequence(
309
 
    project_series INTEGER)
310
 
    RETURNS INTEGER
311
 
LANGUAGE plpgsql AS
312
 
$$
313
 
DECLARE
314
 
    next_sequence INTEGER;
315
 
BEGIN
316
 
    UPDATE projectseriestwin SET counter = counter + 1
317
 
        WHERE id = project_series;
318
 
    SELECT INTO next_sequence counter FROM projectseriestwin
319
 
        WHERE id = project_series;
320
 
    RETURN next_sequence;
321
 
END;
322
 
$$
323
 
""",
324
 
"""
325
 
GRANT EXECUTE
326
 
    ON FUNCTION next_projectseries_sequence(INTEGER)
327
 
    TO lpresults
328
 
""",
329
 
"""
330
288
CREATE FUNCTION testrun_insert_before() RETURNS TRIGGER
331
289
LANGUAGE plpgsql AS
332
290
$$
333
291
BEGIN
334
292
    IF NEW.distro_series IS NOT NULL THEN
335
 
        NEW.sequence = next_distroseries_sequence(NEW.distro_series);
 
293
        UPDATE distroseriestwin SET counter = counter + 1
 
294
            WHERE id = NEW.distro_series RETURNING counter INTO NEW.sequence;
336
295
    ELSIF NEW.project_series IS NOT NULL THEN
337
 
        NEW.sequence = next_projectseries_sequence(NEW.project_series);
 
296
        UPDATE projectseriestwin SET counter = counter + 1
 
297
            WHERE id = NEW.project_series RETURNING counter INTO NEW.sequence;
338
298
    END IF;
339
299
 
340
300
    RETURN NEW;
357
317
LANGUAGE plpgsql AS
358
318
$$
359
319
BEGIN
360
 
    IF NEW.distro_series IS NOT NULL THEN
361
 
        UPDATE testresult SET date_deleted = NEW.date_created
362
 
            WHERE date_deleted = '3000-01-01'
363
 
            AND test_case IN (
364
 
                SELECT id FROM testcase
365
 
                WHERE distro_series = NEW.distro_series);
366
 
    ELSIF NEW.project_series IS NOT NULL THEN
367
 
        UPDATE testresult SET date_deleted = NEW.date_created
368
 
            WHERE date_deleted = '3000-01-01'
369
 
            AND test_case IN (
370
 
                SELECT id FROM testcase
371
 
                WHERE project_series = NEW.project_series);
372
 
    END IF;
 
320
    INSERT INTO testresult (
 
321
            test_case,
 
322
            status,
 
323
            output,
 
324
            date_created,
 
325
            date_deleted)
 
326
        SELECT
 
327
                testresult.test_case,
 
328
                testresult.status,
 
329
                testresult.output,
 
330
                MIN(testrun.date_created),
 
331
                testresult.date_deleted
 
332
            FROM testresult
 
333
            JOIN testrun
 
334
                ON testrun.date_created > NEW.date_created
 
335
                AND testrun.date_created < testresult.date_deleted
 
336
            WHERE testresult.date_created < NEW.date_created
 
337
            AND CASE WHEN NEW.distro_series IS NOT NULL THEN
 
338
                    testrun.distro_series = NEW.distro_series
 
339
                ELSE
 
340
                    testrun.project_series = NEW.project_series
 
341
                END
 
342
            GROUP BY
 
343
                testresult.test_case,
 
344
                testresult.status,
 
345
                testresult.output,
 
346
                testresult.date_deleted;
 
347
 
 
348
    UPDATE testresult
 
349
        SET date_deleted = NEW.date_created
 
350
        FROM testcase
 
351
        WHERE testresult.date_created < NEW.date_created
 
352
        AND testresult.date_deleted > NEW.date_created
 
353
        AND testresult.test_case = testcase.id
 
354
        AND CASE WHEN NEW.distro_series IS NOT NULL THEN
 
355
                testcase.distro_series = NEW.distro_series
 
356
            ELSE
 
357
                testcase.project_series = NEW.project_series
 
358
            END;
373
359
 
374
360
    RETURN NEW;
375
361
END
382
368
""",
383
369
"""
384
370
CREATE TRIGGER testrun_insert_after_trigger
385
 
    BEFORE INSERT ON testrun
 
371
    AFTER INSERT ON testrun
386
372
    FOR EACH ROW
387
373
    EXECUTE PROCEDURE testrun_insert_after()
388
374
""",
389
375
"""
 
376
CREATE FUNCTION testrun_update_before() RETURNS TRIGGER
 
377
LANGUAGE plpgsql AS
 
378
$$
 
379
BEGIN
 
380
    IF OLD.distro_series <> NEW.distro_series THEN
 
381
        RAISE EXCEPTION 'Cannot update distro_series';
 
382
    ELSIF OLD.project_series <> NEW.project_series THEN
 
383
        RAISE EXCEPTION 'Cannot update project_series';
 
384
    ELSIF OLD.date_created <> NEW.date_created THEN
 
385
        RAISE EXCEPTION 'Cannot update project_series';
 
386
    ELSE
 
387
        RETURN NEW;
 
388
    END IF;
 
389
END;
 
390
$$
 
391
""",
 
392
"""
 
393
GRANT EXECUTE
 
394
    ON FUNCTION testrun_update_before()
 
395
    TO lpresults
 
396
""",
 
397
"""
 
398
CREATE TRIGGER testrun_update_before_trigger
 
399
    BEFORE UPDATE ON testrun
 
400
    FOR EACH ROW
 
401
    EXECUTE PROCEDURE testrun_update_before()
 
402
""",
 
403
"""
 
404
CREATE FUNCTION testrun_delete_after() RETURNS TRIGGER
 
405
LANGUAGE plpgsql AS
 
406
$$
 
407
DECLARE
 
408
    next_testrun RECORD;
 
409
BEGIN
 
410
    SELECT
 
411
        INTO next_testrun
 
412
            testrun.date_created
 
413
        FROM testrun
 
414
        WHERE testrun.date_created > OLD.date_created
 
415
        AND CASE WHEN OLD.distro_series IS NOT NULL THEN
 
416
                testrun.distro_series = OLD.distro_series
 
417
            ELSE
 
418
                testrun.project_series = OLD.project_series
 
419
            END
 
420
        ORDER BY testrun.date_created ASC LIMIT 1;
 
421
 
 
422
    -- Between
 
423
    IF next_testrun.date_created IS NOT NULL THEN
 
424
        UPDATE testresult tr1
 
425
            SET date_deleted = tr2.date_deleted
 
426
            FROM testresult tr2, testcase tc
 
427
            WHERE tr1.test_case = tr2.test_case
 
428
            AND tr1.status = tr2.status
 
429
            AND decode(md5(tr1.output), 'hex') = decode(md5(tr2.output), 'hex')
 
430
            AND tr1.date_deleted = OLD.date_created
 
431
            AND tr2.date_created = next_testrun.date_created
 
432
            AND tr1.test_case = tc.id
 
433
            AND CASE WHEN OLD.distro_series IS NOT NULL THEN
 
434
                    tc.distro_series = OLD.distro_series
 
435
                ELSE
 
436
                    tc.project_series = OLD.project_series
 
437
                END;
 
438
        IF FOUND THEN
 
439
            DELETE FROM testresult tr2
 
440
                USING testresult tr1, testcase tc
 
441
                WHERE (
 
442
                    tr1.test_case = tr2.test_case
 
443
                    AND tr1.status = tr2.status
 
444
                    AND decode(md5(tr1.output), 'hex')
 
445
                        = decode(md5(tr2.output), 'hex')
 
446
                    AND tr2.date_created = next_testrun.date_created)
 
447
                OR (
 
448
                    tr2.date_created = OLD.date_created
 
449
                    AND tr2.date_deleted = next_testrun.date_created)
 
450
                AND tr1.test_case = tc.id
 
451
                AND CASE WHEN OLD.distro_series IS NOT NULL THEN
 
452
                        tc.distro_series = OLD.distro_series
 
453
                    ELSE
 
454
                        tc.project_series = OLD.project_series
 
455
                    END;
 
456
        ELSE
 
457
            DELETE FROM testresult tr
 
458
                USING testcase tc
 
459
                WHERE tr.date_created = OLD.date_created
 
460
                AND tr.date_deleted = next_testrun.date_created
 
461
                AND tr.test_case = tc.id
 
462
                AND CASE WHEN OLD.distro_series IS NOT NULL THEN
 
463
                        tc.distro_series = OLD.distro_series
 
464
                    ELSE
 
465
                        tc.project_series = OLD.project_series
 
466
                    END;
 
467
        END IF;
 
468
 
 
469
        -- After
 
470
        UPDATE testresult tr
 
471
            SET date_created = next_testrun.date_created
 
472
            FROM testcase
 
473
            WHERE tr.date_created = OLD.date_created
 
474
            AND tr.test_case = testcase.id
 
475
            AND CASE WHEN OLD.distro_series IS NOT NULL THEN
 
476
                    testcase.distro_series = OLD.distro_series
 
477
                ELSE
 
478
                    testcase.project_series = OLD.project_series
 
479
                END;
 
480
    ELSE
 
481
        next_testrun.date_created = '3000-01-01';
 
482
        DELETE FROM testresult tr
 
483
            USING testcase tc
 
484
            WHERE tr.date_created = OLD.date_created
 
485
            AND tr.test_case = tc.id
 
486
            AND CASE WHEN OLD.distro_series IS NOT NULL THEN
 
487
                    tc.distro_series = OLD.distro_series
 
488
                ELSE
 
489
                    tc.project_series = OLD.project_series
 
490
                END;
 
491
    END IF;
 
492
 
 
493
    -- Before
 
494
    UPDATE testresult tr
 
495
        SET date_deleted = next_testrun.date_created
 
496
        FROM testcase tc
 
497
        WHERE tr.date_deleted = OLD.date_created
 
498
        AND tr.test_case = tc.id
 
499
        AND CASE WHEN OLD.distro_series IS NOT NULL THEN
 
500
                tc.distro_series = OLD.distro_series
 
501
            ELSE
 
502
                tc.project_series = OLD.project_series
 
503
            END;
 
504
 
 
505
    RETURN OLD;
 
506
END;
 
507
$$
 
508
""",
 
509
"""
 
510
GRANT EXECUTE
 
511
    ON FUNCTION testrun_delete_after()
 
512
    TO lpresults
 
513
""",
 
514
"""
 
515
CREATE TRIGGER testrun_delete_after_trigger
 
516
    AFTER DELETE ON testrun
 
517
    FOR EACH ROW
 
518
    EXECUTE PROCEDURE testrun_delete_after()
 
519
""",
 
520
"""
390
521
CREATE FUNCTION testresult_insert_before() RETURNS TRIGGER
391
522
LANGUAGE plpgsql AS
392
523
$$
393
524
DECLARE
394
 
    testresult_record RECORD;
 
525
    next_date_created DATE;
 
526
    next_testrun DATE;
 
527
    previous_date_deleted DATE;
395
528
BEGIN
396
 
    -- First, check for the most common case when
397
 
    -- there is a test result in a backward dimension.
398
 
    SELECT INTO
399
 
        testresult_record
400
 
            testresult.status,
401
 
            testresult.output,
402
 
            testresult.date_created
403
 
        FROM testresult
 
529
    IF NEW.date_deleted < '3000-01-01' THEN
 
530
        RETURN NEW;
 
531
    END IF;
 
532
 
 
533
    SELECT INTO next_testrun
 
534
            CASE WHEN MIN(date_created) > NEW.date_created
 
535
            THEN MIN(date_created)
 
536
            ELSE MIN(date_deleted)
 
537
            END
 
538
        FROM testresult tr
 
539
        JOIN testcase tc1
 
540
            ON tr.test_case = tc1.id
 
541
        JOIN testcase tc2
 
542
            ON tc1.distro_series IS NOT DISTINCT FROM tc2.distro_series
 
543
            AND tc1.project_series IS NOT DISTINCT FROM tc2.project_series
 
544
        WHERE date_deleted > NEW.date_created
 
545
        AND tc2.id = NEW.test_case;
 
546
    IF next_testrun < '3000-01-01' THEN
 
547
        -- Set date created of next test result.
 
548
        UPDATE testresult
 
549
            SET date_created = CASE
 
550
                WHEN testresult.status = NEW.status
 
551
                    AND testresult.output = NEW.output
 
552
                    AND testresult.date_created <> NEW.date_created
 
553
                THEN NEW.date_created
 
554
                ELSE next_testrun
 
555
                END
 
556
            WHERE testresult.test_case = NEW.test_case
 
557
            AND testresult.date_created <= next_testrun
 
558
            AND testresult.date_created >= NEW.date_created
 
559
            RETURNING date_created INTO next_date_created;
 
560
        IF next_date_created != NEW.date_created THEN
 
561
            next_date_created := next_testrun;
 
562
            NEW.date_deleted := next_testrun;
 
563
        END IF;
 
564
    ELSE
 
565
        next_date_created := '3000-01-01';
 
566
    END IF;
 
567
 
 
568
    -- Set date deleted of previous test result.
 
569
    UPDATE testresult
 
570
        SET date_deleted = CASE
 
571
            WHEN testresult.status = NEW.status
 
572
                AND testresult.output = NEW.output
 
573
            THEN next_date_created
 
574
            ELSE NEW.date_created
 
575
            END
404
576
        WHERE testresult.test_case = NEW.test_case
405
577
        AND testresult.date_created <= NEW.date_created
406
 
        AND testresult.date_deleted > NEW.date_created;
407
 
    IF FOUND THEN
408
 
        IF NEW.status = testresult_record.status
409
 
           AND NEW.output = testresult_record.output THEN
410
 
            -- No need to extend forward dimension
411
 
            RETURN NULL;
412
 
 
413
 
        ELSIF NEW.date_created = testresult_record.date_created THEN
414
 
            -- Update current dimension
415
 
            UPDATE testresult SET status = NEW.status, output = NEW.output
416
 
                WHERE testresult.test_case = NEW.test_case
417
 
                AND testresult.date_created <= NEW.date_created
418
 
                AND testresult.date_deleted > NEW.date_created;
419
 
            RETURN NULL;
420
 
 
421
 
        ELSE
422
 
            -- Reducing backward dimension
423
 
            UPDATE testresult SET date_deleted = NEW.date_created
424
 
                WHERE testresult.test_case = NEW.test_case
425
 
                AND testresult.date_created <= NEW.date_created
426
 
                AND testresult.date_deleted > NEW.date_created;
427
 
        END IF;
428
 
    END IF;
429
 
 
430
 
    -- Then, check when there is a test result in a forward dimension.
431
 
    SELECT INTO
432
 
        testresult_record
433
 
            testresult.status,
434
 
            testresult.output,
435
 
            testresult.date_created
436
 
        FROM testresult
437
 
        WHERE testresult.test_case = NEW.test_case
438
 
        AND testresult.date_created > NEW.date_created
439
 
        ORDER BY date_created LIMIT 1;
440
 
    IF FOUND THEN
441
 
        IF NEW.status = testresult_record.status
442
 
           AND NEW.output = testresult_record.output THEN
443
 
            -- Extending forward dimension
444
 
            UPDATE testresult SET date_created = NEW.date_created
445
 
                WHERE testresult.test_case = NEW.test_case
446
 
                AND testresult.date_created = testresult_record.date_created;
447
 
            RETURN NULL;
448
 
 
449
 
        ELSE
450
 
            -- Reducing forward dimension
451
 
            NEW.date_deleted := testresult_record.date_created;
452
 
        END IF;
 
578
        AND testresult.date_deleted >= NEW.date_created
 
579
        RETURNING date_deleted INTO previous_date_deleted;
 
580
    IF previous_date_deleted = next_date_created THEN
 
581
        IF next_date_created = NEW.date_created THEN
 
582
            DELETE FROM testresult
 
583
                WHERE test_case = NEW.test_case
 
584
                AND testresult.date_created = next_testrun;
 
585
        END IF;
 
586
        RETURN NULL;
 
587
    ELSIF next_date_created = NEW.date_created
 
588
          AND previous_date_deleted IS NOT NULL THEN
 
589
        RETURN NULL;
453
590
    END IF;
454
591
 
455
592
    RETURN NEW;
473
610
$$
474
611
BEGIN
475
612
    IF OLD.test_case <> NEW.test_case THEN
476
 
       RAISE EXCEPTION 'Cannot update test_case';
477
 
 
478
 
    ELSIF OLD.status <> NEW.status OR OLD.output <> NEW.output THEN
 
613
        RAISE EXCEPTION 'Cannot update test_case';
 
614
    ELSIF OLD.status <> NEW.status THEN
 
615
        RAISE EXCEPTION 'Cannot update status';
 
616
    ELSIF OLD.output <> NEW.output THEN
 
617
        RAISE EXCEPTION 'Cannot update output';
 
618
    ELSIF NEW.date_deleted = NEW.date_created THEN
479
619
        DELETE FROM testresult
480
620
            WHERE test_case = OLD.test_case
481
621
            AND date_created = OLD.date_created;
482
 
        INSERT INTO testresult (
483
 
                test_case,
484
 
                status,
485
 
                output,
486
 
                date_created,
487
 
                date_deleted)
488
 
            VALUES (
489
 
                NEW.test_case,
490
 
                NEW.status,
491
 
                NEW.output,
492
 
                NEW.date_created,
493
 
                NEW.date_deleted);
494
622
        RETURN NULL;
495
 
 
496
623
    ELSE
497
624
        RETURN NEW;
498
625
    END IF;
511
638
    EXECUTE PROCEDURE testresult_update_before()
512
639
""",
513
640
"""
514
 
CREATE FUNCTION testresult_delete_after() RETURNS TRIGGER
515
 
LANGUAGE plpgsql AS
516
 
$$
517
 
DECLARE
518
 
    testresult_record RECORD;
519
 
BEGIN
520
 
    -- Check if there is a testresult between two equivalent dimensions
521
 
    SELECT INTO testresult_record tr2.date_deleted FROM testresult tr1
522
 
        JOIN testresult tr2
523
 
        ON tr1.test_case = tr2.test_case
524
 
        AND tr1.status = tr2.status
525
 
        AND decode(md5(tr1.output), 'hex') = decode(md5(tr2.output), 'hex')
526
 
        AND tr1.date_deleted = OLD.date_created
527
 
        AND tr2.date_created = OLD.date_deleted;
528
 
    IF FOUND THEN
529
 
        DELETE FROM testresult
530
 
            WHERE testresult.test_case = OLD.test_case
531
 
            AND testresult.date_created = OLD.date_deleted;
532
 
        UPDATE testresult SET date_deleted = testresult_record.date_deleted
533
 
            WHERE testresult.test_case = OLD.test_case
534
 
            AND testresult.date_deleted = OLD.date_created;
535
 
 
536
 
    ELSE
537
 
        -- Extend forward dimension
538
 
        UPDATE testresult SET date_deleted = OLD.date_deleted
539
 
            WHERE testresult.test_case = OLD.test_case
540
 
            AND testresult.date_deleted = OLD.date_created;
541
 
        IF NOT FOUND THEN
542
 
            -- Reduce backward dimension
543
 
            UPDATE testresult set date_created = OLD.date_created
544
 
                WHERE testresult.test_case = OLD.test_case
545
 
                AND testresult.date_created = OLD.date_deleted;
546
 
        END IF;
547
 
    END IF;
548
 
 
549
 
    RETURN OLD;
550
 
END;
551
 
$$
552
 
""",
553
 
"""
554
 
GRANT EXECUTE
555
 
    ON FUNCTION testresult_delete_after()
556
 
    TO lpresults
557
 
""",
558
 
"""
559
 
CREATE TRIGGER testresult_delete_after_trigger
560
 
    AFTER DELETE ON testresult
561
 
    FOR EACH ROW
562
 
    EXECUTE PROCEDURE testresult_delete_after()
563
 
""",
564
 
"""
565
641
ALTER TABLE ONLY testcase
566
642
    ADD CONSTRAINT testcase__distro_series__fk
567
643
    FOREIGN KEY (distro_series)
606
682
]
607
683
 
608
684
DROPS = [
609
 
"DROP FUNCTION testresult_delete_after()",
610
685
"DROP FUNCTION testresult_update_before()",
611
686
"DROP FUNCTION testresult_insert_before()",
 
687
"DROP FUNCTION testrun_delete_after()",
 
688
"DROP FUNCTION testrun_update_before()",
612
689
"DROP FUNCTION testrun_insert_after()",
613
690
"DROP FUNCTION testrun_insert_before()",
614
 
"DROP FUNCTION next_projectseries_sequence(INTEGER)",
615
 
"DROP FUNCTION next_distroseries_sequence(INTEGER)",
616
691
"DROP FUNCTION add_test_result(INTEGER, INTEGER, TEXT, TIMESTAMP)",
617
692
"DROP FUNCTION get_test_case(INTEGER, INTEGER, TEXT)",
618
693
"DROP LANGUAGE plpgsql",