From 0e73a8992e13f116a1ccf57a4cbfbca8004e4835 Mon Sep 17 00:00:00 2001
From: Andre Anjos <andre.dos.anjos@gmail.com>
Date: Wed, 18 May 2016 12:27:01 +0200
Subject: [PATCH] [experiments,search] Fix Rank reset after experiment
 migrations

---
 .../migrations/0002_scheduler_addons.py       | 18 +++--
 .../migrations/0003_scheduler_addons_2.py     | 20 +++---
 .../migrations/0004_scheduler_addons_3.py     |  4 ++
 .../migrations/0002_scheduler_addons.py       | 65 +++++++++++++++++++
 4 files changed, 92 insertions(+), 15 deletions(-)
 create mode 100644 beat/web/search/migrations/0002_scheduler_addons.py

diff --git a/beat/web/experiments/migrations/0002_scheduler_addons.py b/beat/web/experiments/migrations/0002_scheduler_addons.py
index 9c7507834..a1f462385 100644
--- a/beat/web/experiments/migrations/0002_scheduler_addons.py
+++ b/beat/web/experiments/migrations/0002_scheduler_addons.py
@@ -31,6 +31,19 @@ from __future__ import unicode_literals
 from django.db import migrations, models
 
 
+def move_result_to_cache(apps, schema_editor):
+    '''Moves the result association from the block to the related cache file'''
+
+    Result = apps.get_model("experiments", "Result")
+
+    total = Result.objects.count()
+    if total: print('')
+    for i, r in enumerate(Result.objects.order_by('-id')):
+        print("Resetting result (%d) %d/%d..." % (r.id, i+1, total))
+        r.cache = r.block.hashes.first()
+        r.save()
+
+
 class Migration(migrations.Migration):
 
     dependencies = [
@@ -44,8 +57,5 @@ class Migration(migrations.Migration):
             field=models.ForeignKey(related_name='results',
               to='experiments.CachedFile', null=True),
         ),
-        migrations.AlterUniqueTogether(
-            name='result',
-            unique_together=set([('cache', 'name')]),
-        ),
+        migrations.RunPython(move_result_to_cache),
     ]
diff --git a/beat/web/experiments/migrations/0003_scheduler_addons_2.py b/beat/web/experiments/migrations/0003_scheduler_addons_2.py
index 65e9b37bd..3d72f2965 100644
--- a/beat/web/experiments/migrations/0003_scheduler_addons_2.py
+++ b/beat/web/experiments/migrations/0003_scheduler_addons_2.py
@@ -31,30 +31,28 @@ from __future__ import unicode_literals
 from django.db import migrations
 
 
-def move_result_to_cache(apps, schema_editor):
-    '''Moves the result association from the block to the related cache file'''
+def dedup_resuls(apps, schema_editor):
+    '''Deletes duplicated results (older ones)'''
 
     Result = apps.get_model("experiments", "Result")
 
-    total = Result.objects.count()
-    if total: print('')
-    for i, r in enumerate(Result.objects.order_by('id')):
-        print("Resetting result (%d) %d/%d..." % (r.id, i+1, total))
-        older = Result.objects.filter(name=r.name, cache=r.block.hashes.first()).exclude(id=r.id).first()
+    for i, r in enumerate(Result.objects.order_by('-id')):
+        older = Result.objects.filter(name=r.name, id__lt=r.id,
+            cache=r.block.hashes.first())
         if older:
             print("Cache %s already contains Result `%s' - keeping " \
-                "newest..." % (older.cache.hash, older.name))
+                "newest (out of %d)..." % (r.block.hashes.first().hash, r.name,
+                  older.count()+1))
             older.delete()
-        r.cache = r.block.hashes.first()
-        r.save()
 
 
 class Migration(migrations.Migration):
 
     dependencies = [
         ('experiments', '0002_scheduler_addons'),
+        ('search', '0002_scheduler_addons'),
     ]
 
     operations = [
-        migrations.RunPython(move_result_to_cache),
+        migrations.RunPython(dedup_resuls),
         ]
diff --git a/beat/web/experiments/migrations/0004_scheduler_addons_3.py b/beat/web/experiments/migrations/0004_scheduler_addons_3.py
index fcd721050..77c7dba1e 100644
--- a/beat/web/experiments/migrations/0004_scheduler_addons_3.py
+++ b/beat/web/experiments/migrations/0004_scheduler_addons_3.py
@@ -216,6 +216,10 @@ class Migration(migrations.Migration):
     ]
 
     operations = [
+        migrations.AlterUniqueTogether(
+            name='result',
+            unique_together=set([('cache', 'name')]),
+        ),
         migrations.RemoveField(
             model_name='result',
             name='block',
diff --git a/beat/web/search/migrations/0002_scheduler_addons.py b/beat/web/search/migrations/0002_scheduler_addons.py
new file mode 100644
index 000000000..f269a5f4a
--- /dev/null
+++ b/beat/web/search/migrations/0002_scheduler_addons.py
@@ -0,0 +1,65 @@
+#!/usr/bin/env python
+# vim: set fileencoding=utf-8 :
+
+###############################################################################
+#                                                                             #
+# Copyright (c) 2016 Idiap Research Institute, http://www.idiap.ch/           #
+# Contact: beat.support@idiap.ch                                              #
+#                                                                             #
+# This file is part of the beat.web module of the BEAT platform.              #
+#                                                                             #
+# Commercial License Usage                                                    #
+# Licensees holding valid commercial BEAT licenses may use this file in       #
+# accordance with the terms contained in a written agreement between you      #
+# and Idiap. For further information contact tto@idiap.ch                     #
+#                                                                             #
+# Alternatively, this file may be used under the terms of the GNU Affero      #
+# Public License version 3 as published by the Free Software and appearing    #
+# in the file LICENSE.AGPL included in the packaging of this file.            #
+# The BEAT platform is distributed in the hope that it will be useful, but    #
+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY  #
+# or FITNESS FOR A PARTICULAR PURPOSE.                                        #
+#                                                                             #
+# You should have received a copy of the GNU Affero Public License along      #
+# with the BEAT platform. If not, see http://www.gnu.org/licenses/.           #
+#                                                                             #
+###############################################################################
+
+
+from __future__ import unicode_literals
+
+from django.db import migrations
+
+
+def reset_ranks(apps, schema_editor):
+    '''Reset ranks before older results can be deleted'''
+
+    Result = apps.get_model("experiments", "Result")
+    Rank = apps.get_model("search", "Rank")
+
+    total = Result.objects.count()
+    if total: print('')
+    for i, r in enumerate(Result.objects.order_by('-id')):
+        older = Result.objects.filter(name=r.name, id__lt=r.id,
+            cache=r.block.hashes.first())
+        for old in older:
+            # check if any leaderboard ranks require updates
+            for rank in Rank.objects.filter(result__in=(old,)):
+                print("Rank %d for search `%s/%s' uses old Result `%d' - " \
+                    "resetting to newer Result `%d'..." % \
+                    (rank.id, rank.leaderboard.search.author.username,
+                      rank.leaderboard.search.name, old.id, r.id))
+                rank.result.remove(old)
+                rank.result.add(r)
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('search', '0001_initial'),
+        ('experiments', '0002_scheduler_addons'),
+    ]
+
+    operations = [
+        migrations.RunPython(reset_ranks),
+        ]
-- 
GitLab