From 15aa7da858cf433ce4add5ae067b46acd10bfaca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Barrag=C3=A1n=20Merino?= Date: Thu, 28 Jul 2016 12:23:44 +0200 Subject: [PATCH] Apply some fixes over epic custom attributes --- .../migrations/0008_auto_20160728_0540.py | 95 ++++++++++--------- ...630_0849.py => 0009_auto_20160728_1002.py} | 26 ++--- taiga/projects/custom_attributes/models.py | 1 + 3 files changed, 65 insertions(+), 57 deletions(-) rename taiga/projects/custom_attributes/migrations/{0008_auto_20160630_0849.py => 0009_auto_20160728_1002.py} (88%) diff --git a/taiga/projects/custom_attributes/migrations/0008_auto_20160728_0540.py b/taiga/projects/custom_attributes/migrations/0008_auto_20160728_0540.py index 6f2d86f7..4c0509bb 100644 --- a/taiga/projects/custom_attributes/migrations/0008_auto_20160728_0540.py +++ b/taiga/projects/custom_attributes/migrations/0008_auto_20160728_0540.py @@ -15,50 +15,50 @@ class Migration(migrations.Migration): # Function: Remove a key in a json field migrations.RunSQL( """ - CREATE OR REPLACE FUNCTION "json_object_delete_keys"("json" json, VARIADIC "keys_to_delete" text[]) - RETURNS json - LANGUAGE sql - IMMUTABLE - STRICT - AS $function$ - SELECT COALESCE ((SELECT ('{' || string_agg(to_json("key") || ':' || "value", ',') || '}') - FROM json_each("json") - WHERE "key" <> ALL ("keys_to_delete")), - '{}')::json $function$; + CREATE OR REPLACE FUNCTION "json_object_delete_keys"("json" json, VARIADIC "keys_to_delete" text[]) + RETURNS json + LANGUAGE sql + IMMUTABLE + STRICT + AS $function$ + SELECT COALESCE ((SELECT ('{' || string_agg(to_json("key") || ':' || "value", ',') || '}') + FROM json_each("json") + WHERE "key" <> ALL ("keys_to_delete")), + '{}')::json $function$; """, - reverse_sql="""DROP FUNCTION IF EXISTS "json_object_delete_keys"("json" json, VARIADIC "keys_to_delete" text[]) - CASCADE;""" + reverse_sql=""" + DROP FUNCTION IF EXISTS "json_object_delete_keys"("json" json, VARIADIC "keys_to_delete" text[]) + CASCADE;""" ), # Function: Romeve a key in the json field of *_custom_attributes_values.values migrations.RunSQL( """ - CREATE OR REPLACE FUNCTION "clean_key_in_custom_attributes_values"() - RETURNS trigger - AS $clean_key_in_custom_attributes_values$ - DECLARE - key text; - project_id int; - object_id int; - attribute text; - tablename text; - custom_attributes_tablename text; - BEGIN - key := OLD.id::text; - project_id := OLD.project_id; - attribute := TG_ARGV[0]::text; - tablename := TG_ARGV[1]::text; - custom_attributes_tablename := TG_ARGV[2]::text; - - EXECUTE 'UPDATE ' || quote_ident(custom_attributes_tablename) || ' - SET attributes_values = json_object_delete_keys(attributes_values, ' || quote_literal(key) || ') - FROM ' || quote_ident(tablename) || ' - WHERE ' || quote_ident(tablename) || '.project_id = ' || project_id || ' - AND ' || quote_ident(custom_attributes_tablename) || '.' || quote_ident(attribute) || ' = ' || quote_ident(tablename) || '.id'; - RETURN NULL; - END; $clean_key_in_custom_attributes_values$ - LANGUAGE plpgsql; + CREATE OR REPLACE FUNCTION "clean_key_in_custom_attributes_values"() + RETURNS trigger + AS $clean_key_in_custom_attributes_values$ + DECLARE + key text; + project_id int; + object_id int; + attribute text; + tablename text; + custom_attributes_tablename text; + BEGIN + key := OLD.id::text; + project_id := OLD.project_id; + attribute := TG_ARGV[0]::text; + tablename := TG_ARGV[1]::text; + custom_attributes_tablename := TG_ARGV[2]::text; + EXECUTE 'UPDATE ' || quote_ident(custom_attributes_tablename) || ' + SET attributes_values = json_object_delete_keys(attributes_values, ' || quote_literal(key) || ') + FROM ' || quote_ident(tablename) || ' + WHERE ' || quote_ident(tablename) || '.project_id = ' || project_id || ' + AND ' || quote_ident(custom_attributes_tablename) || '.' || quote_ident(attribute) || ' = ' || quote_ident(tablename) || '.id'; + RETURN NULL; + END; $clean_key_in_custom_attributes_values$ + LANGUAGE plpgsql; """ ), @@ -66,13 +66,14 @@ class Migration(migrations.Migration): migrations.RunSQL( """ DROP TRIGGER IF EXISTS "update_userstorycustomvalues_after_remove_userstorycustomattribute" - ON custom_attributes_userstorycustomattribute - CASCADE; + ON custom_attributes_userstorycustomattribute + CASCADE; CREATE TRIGGER "update_userstorycustomvalues_after_remove_userstorycustomattribute" AFTER DELETE ON custom_attributes_userstorycustomattribute FOR EACH ROW - EXECUTE PROCEDURE clean_key_in_custom_attributes_values('user_story_id', 'userstories_userstory', 'custom_attributes_userstorycustomattributesvalues'); + EXECUTE PROCEDURE clean_key_in_custom_attributes_values('user_story_id', 'userstories_userstory', + 'custom_attributes_userstorycustomattributesvalues'); """ ), @@ -80,13 +81,14 @@ class Migration(migrations.Migration): migrations.RunSQL( """ DROP TRIGGER IF EXISTS "update_taskcustomvalues_after_remove_taskcustomattribute" - ON custom_attributes_taskcustomattribute - CASCADE; + ON custom_attributes_taskcustomattribute + CASCADE; CREATE TRIGGER "update_taskcustomvalues_after_remove_taskcustomattribute" AFTER DELETE ON custom_attributes_taskcustomattribute FOR EACH ROW - EXECUTE PROCEDURE clean_key_in_custom_attributes_values('task_id', 'tasks_task', 'custom_attributes_taskcustomattributesvalues'); + EXECUTE PROCEDURE clean_key_in_custom_attributes_values('task_id', 'tasks_task', + 'custom_attributes_taskcustomattributesvalues'); """ ), @@ -94,13 +96,14 @@ class Migration(migrations.Migration): migrations.RunSQL( """ DROP TRIGGER IF EXISTS "update_issuecustomvalues_after_remove_issuecustomattribute" - ON custom_attributes_issuecustomattribute - CASCADE; + ON custom_attributes_issuecustomattribute + CASCADE; CREATE TRIGGER "update_issuecustomvalues_after_remove_issuecustomattribute" AFTER DELETE ON custom_attributes_issuecustomattribute FOR EACH ROW - EXECUTE PROCEDURE clean_key_in_custom_attributes_values('issue_id', 'issues_issue', 'custom_attributes_issuecustomattributesvalues'); + EXECUTE PROCEDURE clean_key_in_custom_attributes_values('issue_id', 'issues_issue', + 'custom_attributes_issuecustomattributesvalues'); """ ), migrations.AlterIndexTogether( diff --git a/taiga/projects/custom_attributes/migrations/0008_auto_20160630_0849.py b/taiga/projects/custom_attributes/migrations/0009_auto_20160728_1002.py similarity index 88% rename from taiga/projects/custom_attributes/migrations/0008_auto_20160630_0849.py rename to taiga/projects/custom_attributes/migrations/0009_auto_20160728_1002.py index bcb7668c..313e22fd 100644 --- a/taiga/projects/custom_attributes/migrations/0008_auto_20160630_0849.py +++ b/taiga/projects/custom_attributes/migrations/0009_auto_20160728_1002.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Generated by Django 1.9.2 on 2016-06-30 08:49 +# Generated by Django 1.9.2 on 2016-07-28 10:02 from __future__ import unicode_literals from django.db import migrations, models @@ -11,12 +11,13 @@ import django_pgjson.fields class Migration(migrations.Migration): dependencies = [ - ('epics', '0001_initial'), - ('projects', '0049_auto_20160629_1443'), - ('custom_attributes', '0007_auto_20160208_1751'), + ('epics', '0002_epic_color'), + ('projects', '0050_project_epics_csv_uuid'), + ('custom_attributes', '0008_auto_20160728_0540'), ] operations = [ + # Change some verbose names migrations.AlterModelOptions( name='issuecustomattributesvalues', options={'ordering': ['id'], 'verbose_name': 'issue custom attributes values', 'verbose_name_plural': 'issue custom attributes values'}, @@ -29,7 +30,7 @@ class Migration(migrations.Migration): name='userstorycustomattributesvalues', options={'ordering': ['id'], 'verbose_name': 'user story custom attributes values', 'verbose_name_plural': 'user story custom attributes values'}, ), - + # Custom attributes for epics migrations.CreateModel( name='EpicCustomAttribute', fields=[ @@ -43,10 +44,10 @@ class Migration(migrations.Migration): ('project', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='epiccustomattributes', to='projects.Project', verbose_name='project')), ], options={ - 'verbose_name_plural': 'epic custom attributes', 'verbose_name': 'epic custom attribute', 'abstract': False, 'ordering': ['project', 'order', 'name'], + 'verbose_name_plural': 'epic custom attributes', }, ), migrations.CreateModel( @@ -58,24 +59,27 @@ class Migration(migrations.Migration): ('epic', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='custom_attributes_values', to='epics.Epic', verbose_name='epic')), ], options={ - 'verbose_name_plural': 'epic custom attributes values', - 'verbose_name': 'epic custom attributes values', 'abstract': False, + 'verbose_name': 'epic custom attributes values', 'ordering': ['id'], + 'verbose_name_plural': 'epic custom attributes values', }, ), + migrations.AlterIndexTogether( + name='epiccustomattributesvalues', + index_together=set([('epic',)]), + ), migrations.AlterUniqueTogether( name='epiccustomattribute', unique_together=set([('project', 'name')]), ), - - # Trigger: Clean epiccustomattributes values before remove a epiccustomattribute migrations.RunSQL( """ CREATE TRIGGER "update_epiccustomvalues_after_remove_epiccustomattribute" AFTER DELETE ON custom_attributes_epiccustomattribute FOR EACH ROW - EXECUTE PROCEDURE clean_key_in_custom_attributes_values('custom_attributes_epiccustomattributesvalues'); + EXECUTE PROCEDURE clean_key_in_custom_attributes_values('epic_id', 'epics_epic', + 'custom_attributes_epiccustomattributesvalues'); """, reverse_sql="""DROP TRIGGER IF EXISTS "update_epiccustomvalues_after_remove_epiccustomattribute" ON custom_attributes_epiccustomattribute diff --git a/taiga/projects/custom_attributes/models.py b/taiga/projects/custom_attributes/models.py index 8b5747f0..4fa6978b 100644 --- a/taiga/projects/custom_attributes/models.py +++ b/taiga/projects/custom_attributes/models.py @@ -106,6 +106,7 @@ class EpicCustomAttributesValues(AbstractCustomAttributesValues): class Meta(AbstractCustomAttributesValues.Meta): verbose_name = "epic custom attributes values" verbose_name_plural = "epic custom attributes values" + index_together = [("epic",)] @property def project(self):