Adding migrations

remotes/origin/issue/4795/notification_even_they_are_disabled
Alejandro Alonso 2016-06-07 09:13:38 +02:00 committed by David Barragán Merino
parent 20c350ea63
commit 7134d04262
2 changed files with 216 additions and 0 deletions

View File

@ -0,0 +1,192 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.2 on 2016-06-07 06:19
from __future__ import unicode_literals
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('projects', '0045_merge'),
]
operations = [
# Function: Reduce a multidimensional array only on its first level
migrations.RunSQL(
"""
CREATE OR REPLACE FUNCTION public.reduce_dim(anyarray)
RETURNS SETOF anyarray
AS $function$
DECLARE
s $1%TYPE;
BEGIN
FOREACH s SLICE 1 IN ARRAY $1 LOOP
RETURN NEXT s;
END LOOP;
RETURN;
END;
$function$
LANGUAGE plpgsql IMMUTABLE;
"""
),
# Function: aggregates multi dimensional arrays
migrations.RunSQL(
"""
DROP AGGREGATE IF EXISTS array_agg_mult (anyarray);
CREATE AGGREGATE array_agg_mult (anyarray) (
SFUNC = array_cat
,STYPE = anyarray
,INITCOND = '{}'
);
"""
),
# Function: array_distinct
migrations.RunSQL(
"""
CREATE OR REPLACE FUNCTION array_distinct(anyarray)
RETURNS anyarray AS $$
SELECT ARRAY(SELECT DISTINCT unnest($1))
$$ LANGUAGE sql;
"""
),
# Rebuild the color tags so it's consisten in any project
migrations.RunSQL(
"""
WITH
tags_colors AS (
SELECT id project_id, reduce_dim(tags_colors) tags_colors
FROM projects_project
WHERE tags_colors != '{}'
),
tags AS (
SELECT unnest(tags) tag, NULL color, project_id FROM userstories_userstory
UNION
SELECT unnest(tags) tag, NULL color, project_id FROM tasks_task
UNION
SELECT unnest(tags) tag, NULL color, project_id FROM issues_issue
UNION
SELECT unnest(tags) tag, NULL color, id project_id FROM projects_project
),
rebuilt_tags_colors AS (
SELECT tags.project_id project_id,
array_agg_mult(ARRAY[[tags.tag, tags_colors.tags_colors[2]]]) tags_colors
FROM tags
LEFT JOIN tags_colors ON
tags_colors.project_id = tags.project_id AND
tags_colors[1] = tags.tag
GROUP BY tags.project_id
)
UPDATE projects_project
SET tags_colors = rebuilt_tags_colors.tags_colors
FROM rebuilt_tags_colors
WHERE rebuilt_tags_colors.project_id = projects_project.id;
"""
),
# Trigger for auto updating projects_project.tags_colors
migrations.RunSQL(
"""
CREATE OR REPLACE FUNCTION update_project_tags_colors()
RETURNS trigger AS $update_project_tags_colors$
DECLARE
tags text[];
project_tags_colors text[];
tag_color text[];
project_tags text[];
tag text;
project_id integer;
BEGIN
tags := NEW.tags::text[];
project_id := NEW.project_id::integer;
project_tags := '{}';
-- Read project tags_colors into project_tags_colors
SELECT projects_project.tags_colors INTO project_tags_colors
FROM projects_project
WHERE id = project_id;
-- Extract just the project tags to project_tags_colors
IF project_tags_colors != ARRAY[]::text[] THEN
FOREACH tag_color SLICE 1 in ARRAY project_tags_colors
LOOP
project_tags := array_append(project_tags, tag_color[1]);
END LOOP;
END IF;
-- Add to project_tags_colors the new tags
IF tags IS NOT NULL THEN
FOREACH tag in ARRAY tags
LOOP
IF tag != ALL(project_tags) THEN
project_tags_colors := array_cat(project_tags_colors,
ARRAY[ARRAY[tag, NULL]]);
END IF;
END LOOP;
END IF;
-- Save the result in the tags_colors column
UPDATE projects_project
SET tags_colors = project_tags_colors
WHERE id = project_id;
RETURN NULL;
END; $update_project_tags_colors$
LANGUAGE plpgsql;
"""
),
# Execute trigger after user_story update
migrations.RunSQL(
"""
DROP TRIGGER IF EXISTS update_project_tags_colors_on_userstory_update ON userstories_userstory;
CREATE TRIGGER update_project_tags_colors_on_userstory_update
AFTER UPDATE ON userstories_userstory
FOR EACH ROW EXECUTE PROCEDURE update_project_tags_colors();
"""
),
# Execute trigger after user_story insert
migrations.RunSQL(
"""
DROP TRIGGER IF EXISTS update_project_tags_colors_on_userstory_insert ON userstories_userstory;
CREATE TRIGGER update_project_tags_colors_on_userstory_insert
AFTER INSERT ON userstories_userstory
FOR EACH ROW EXECUTE PROCEDURE update_project_tags_colors();
"""
),
# Execute trigger after task update
migrations.RunSQL(
"""
DROP TRIGGER IF EXISTS update_project_tags_colors_on_task_update ON tasks_task;
CREATE TRIGGER update_project_tags_colors_on_task_update
AFTER UPDATE ON tasks_task
FOR EACH ROW EXECUTE PROCEDURE update_project_tags_colors();
"""
),
# Execute trigger after task insert
migrations.RunSQL(
"""
DROP TRIGGER IF EXISTS update_project_tags_colors_on_task_insert ON tasks_task;
CREATE TRIGGER update_project_tags_colors_on_task_insert
AFTER INSERT ON tasks_task
FOR EACH ROW EXECUTE PROCEDURE update_project_tags_colors();
"""
),
# Execute trigger after issue update
migrations.RunSQL(
"""
DROP TRIGGER IF EXISTS update_project_tags_colors_on_issue_update ON issues_issue;
CREATE TRIGGER update_project_tags_colors_on_issue_update
AFTER UPDATE ON issues_issue
FOR EACH ROW EXECUTE PROCEDURE update_project_tags_colors();
"""
),
# Execute trigger after issue insert
migrations.RunSQL(
"""
DROP TRIGGER IF EXISTS update_project_tags_colors_on_issue_insert ON issues_issue;
CREATE TRIGGER update_project_tags_colors_on_issue_insert
AFTER INSERT ON issues_issue
FOR EACH ROW EXECUTE PROCEDURE update_project_tags_colors();
"""
),
]

View File

@ -1852,3 +1852,27 @@ def test_delete_project_with_celery_disabled(client, settings):
response = client.json.delete(url) response = client.json.delete(url)
assert response.status_code == 204 assert response.status_code == 204
assert Project.objects.filter(id=project.id).count() == 0 assert Project.objects.filter(id=project.id).count() == 0
def test_color_tags_project_fired_on_element_create():
user_story = f.UserStoryFactory.create(tags=["tag"])
project = Project.objects.get(id=user_story.project.id)
assert project.tags_colors == [["tag", None]]
def test_color_tags_project_fired_on_element_update():
user_story = f.UserStoryFactory.create()
user_story.tags = ["tag"]
user_story.save()
project = Project.objects.get(id=user_story.project.id)
assert project.tags_colors == [["tag", None]]
def test_color_tags_project_fired_on_element_update_respecting_color():
project = f.ProjectFactory.create(tags_colors=[["tag", "#123123"]])
user_story = f.UserStoryFactory.create(project=project)
user_story.tags = ["tag"]
user_story.save()
project = Project.objects.get(id=user_story.project.id)
assert project.tags_colors == [["tag", "#123123"]]
>>>>>>> d64d158... WIP: migrations, removing automatic color generation