changeset 316:e80f63d8ddc3

Migrate FieldValue + other docs on trackers
author Sylvain Beucler <beuc@beuc.net>
date Tue, 17 Aug 2010 23:17:08 +0200
parents 759c15d54ca4
children b89bb28a8c80
files migrate_old_savane.sql savane/svmain/models.py savane/tracker/models.py
diffstat 3 files changed, 86 insertions(+), 11 deletions(-) [+]
line wrap: on
line diff
--- a/migrate_old_savane.sql
+++ b/migrate_old_savane.sql
@@ -484,6 +484,7 @@
 -- TRACKERS
 ----
 
+TRUNCATE tracker_tracker;
 INSERT INTO tracker_tracker (`name`) VALUES ('bugs');
 INSERT INTO tracker_tracker (`name`) VALUES ('patch');
 INSERT INTO tracker_tracker (`name`) VALUES ('support');
@@ -532,7 +533,9 @@
     FROM_UNIXTIME(IF(custom_df5<0,0,custom_df5))
     FROM savane_old.bugs;
 
--- We're merging all the *_field tables, so we need to assign new ids
+-- We're merging all the *_field tables, so we need to assign new ids.
+-- (Not needed if we merge the tracker fields definitions, because
+-- they are mostly identical (cf. models.py).)
 CREATE TEMPORARY TABLE conv_field_ids (
   new INT auto_increment PRIMARY KEY,
   tracker_id VARCHAR(7), old INT,
@@ -592,6 +595,32 @@
       IFNULL(custom_keep_history, 0), transition_default_auth
    FROM temp_bugs_field_usage JOIN conv_field_ids
       ON (bug_field_id = old AND tracker_id = 'bugs');
+DROP TABLE temp_bugs_field_usage;
 -- Specify "default" differently
 UPDATE tracker_fieldusage SET group_id=NULL WHERE group_id=100;
-DROP TABLE temp_bugs_field_usage;
+
+-- Get rid of duplicates (old mysql/php/savane bug?)
+-- Apparently this affects 'None' values.
+-- Give priority to the last one (arbitrarily).
+-- Need to create a real table - a temporary one has issues with being "reopened" in joins
+DELETE FROM savane_old.bugs_field_value
+  WHERE bug_fv_id IN (
+    SELECT bug_fv_id FROM (
+      SELECT B.bug_fv_id FROM savane_old.bugs_field_value A, savane_old.bugs_field_value B
+        WHERE A.bug_fv_id > B.bug_fv_id
+          AND A.bug_field_id = B.bug_field_id AND A.group_id = B.group_id AND A.value_id = B.value_id
+      ) AS temp
+    );
+-- id <- <auto>
+-- field_id <- bug_field_id
+TRUNCATE tracker_fieldvalue;
+INSERT INTO tracker_fieldvalue
+    (field_id, group_id, value_id, `value`, description,
+     order_id, status, email_ad, send_all_flag)
+  SELECT
+     conv_field_ids.new, group_id, value_id, `value`, description,
+     order_id, status, email_ad, send_all_flag
+   FROM savane_old.bugs_field_value JOIN conv_field_ids
+      ON (bug_field_id = old AND tracker_id = 'bugs');
+-- Specify "default" differently
+UPDATE tracker_fieldvalue SET group_id=NULL WHERE group_id=100;
--- a/savane/svmain/models.py
+++ b/savane/svmain/models.py
@@ -134,7 +134,7 @@
     # Allow a user to counter-act an account hijack
     email_hash_cancel = models.BigIntegerField(blank=True, null=True)
     # The new e-mail to use if validated
-    email_new = models.EmailField(_("new e-mail address"))
+    email_new = models.EmailField(_("new e-mail address"), blank=True, null=True)
 
     # Keys
     gpg_key = models.TextField(blank=True,
@@ -145,7 +145,7 @@
     # Preferences - /!\ some are also in the user_preferences table
     email_hide = models.BooleanField(default=False)
     timezone = models.CharField(max_length=192, blank=True)
-    theme = models.CharField(max_length=45, blank=True)
+    #theme = models.CharField(max_length=45, blank=True)
 
     superuser_is_enabled = models.BooleanField(default=False)
 
--- a/savane/tracker/models.py
+++ b/savane/tracker/models.py
@@ -232,6 +232,49 @@
     """
     Field configuration overlay for each group
     group == NULL means default
+
+
+    Differences between trackers for default values:
+
+    SELECT COUNT(*) FROM (
+            SELECT bug_field_id FROM bugs_field_usage
+      UNION SELECT bug_field_id FROM patch_field_usage
+      UNION SELECT bug_field_id FROM support_field_usage
+      UNION SELECT bug_field_id FROM task_field_usage
+    ) subquery;
+    => 73
+
+    SELECT bug_field_id, COUNT(*) FROM (
+            SELECT * FROM bugs_field_usage    WHERE group_id=100
+      UNION SELECT * FROM patch_field_usage   WHERE group_id=100
+      UNION SELECT * FROM support_field_usage WHERE group_id=100
+      UNION SELECT * FROM task_field_usage    WHERE group_id=100
+    ) subquery GROUP BY bug_field_id HAVING COUNT(*) > 2;
+    +--------------+----------+
+    | bug_field_id | COUNT(*) |
+    +--------------+----------+
+    |           92 |        2 | submitted_by
+    |          102 |        2 | severity
+    |          107 |        2 | bug_group_id
+    |          201 |        2 | platform_version_id
+    |          206 |        2 | hours
+    |          211 |        4 | priority
+    |          216 |        2 | originator_email
+    |          220 |        2 | percent_complete
+    +--------------+----------+
+
+     92 -> (use_it=0)(patch,support) | (use_it=1)(bugs,task)
+    102 -> (use_it,show_on_add,show_on_add_members=0)(patch,task) | (use_it,show_on_add,show_on_add_members=1)(bugs,support)
+    107 -> (show_on_add,show_on_add_members=0)(patch,support) | (show_on_add,show_on_add_members=1)(bugs,task) [but use_it=0]
+    201 -> (use_it,show_on_add,show_on_add_members=0)(bugs,patch,task) | (use_it,show_on_add,show_on_add_members=1)(support)
+    201 -> (use_it,show_on_add,show_on_add_members=0)(bugs,patch,support) | (use_it,show_on_add,show_on_add_members=1)(task)
+    211 -> (show_on_add,show_on_add_members,place)
+           bugs: 0,1,200
+           patch: 1,1,150
+           support: 0,0,150
+           task: 1,1,200
+    216 -> (use_it,show_on_add=0)(task) | (use_it=1,show_on_add=2)(bugs,patch,support)
+    220 -> (use_it,show_on_add_members=0)(bugs,patch,support) | (use_it,show_on_add_members=1)(task)
     """
     class Meta:
         unique_together = (('field', 'group'),)
@@ -282,16 +325,16 @@
 
 class FieldValue(models.Model):
     """
-    Choice for a select-box (SB) field of a specific group
+    Choices overlay for a select-box (SB) field of a specific group
     """
     class Meta:
-        unique_together = (('bug_field', 'group', 'value_id'),)
+        unique_together = (('field', 'group', 'value_id'),)
 
     STATUS_CHOICES = (('A', _('active')),
                       ('H', _('hidden')), # mask previously-active or system fields
                       ('P', _('permanent')),) # status cannot be modified, always visible
-    bug_field = models.ForeignKey('Field')
-    group = models.ForeignKey(auth_models.Group) # =100 for system-wide values
+    field = models.ForeignKey('Field')
+    group = models.ForeignKey(auth_models.Group, blank=True, null=True, help_text=_("NULL == default"))
     value_id = models.IntegerField(db_index=True) # group_specific value identifier
       # It's not a duplicate of 'id', as it's the value referenced by
       # Item fields, and the configuration of that value can be
@@ -302,7 +345,8 @@
     status = models.CharField(max_length=1, choices=STATUS_CHOICES, default='A', db_index=True)
 
     # Field category: specific (bad!) field for e-mail notifications
-    email_ad = models.TextField(help_text=_("comma-separated list of e-mail addresses to notify when an item is created or modified in this category"))
+    email_ad = models.TextField(blank=True, null=True,
+                                help_text=_("comma-separated list of e-mail addresses to notify when an item is created or modified in this category"))
     send_all_flag = models.BooleanField(_("send on all updates"), default=True)
 
 # Auto_increment counters
@@ -358,8 +402,10 @@
     # To avoid unnecessary burden, let's drop the above incomplete ForeignKey
 
     # More generally one can wonder if this should be moved to a M2M
-    # bug<->field table; but after we're done with the migration from
-    # the previous database :)
+    # item<->field_value table; but after we're done with the
+    # migration from the previous database :) Plus it might just be
+    # cumbersome, given there's already several hardcoded fields
+    # behavior.
 
     # - fields with hard-coded processing
     summary = models.TextField()