From 7b0db234e2faa31f94013dd4ba4f0ee3de8c4359 Mon Sep 17 00:00:00 2001
From: Eliot Berriot <contact@eliotberriot.com>
Date: Tue, 17 Dec 2019 10:57:05 +0100
Subject: [PATCH] Revert "Fix #994: use PostgreSQL full-text-search"

This reverts commit b3d8d6a4dac979cd2eef52488264d7e2da21b40d.
---
 api/config/settings/common.py                 |   1 -
 api/funkwhale_api/common/search.py            |  12 --
 .../music/migrations/0044_full_text_search.py | 109 ------------------
 api/funkwhale_api/music/models.py             |  10 +-
 api/funkwhale_api/music/utils.py              |   6 +-
 api/funkwhale_api/music/views.py              |  15 +--
 6 files changed, 5 insertions(+), 148 deletions(-)
 delete mode 100644 api/funkwhale_api/music/migrations/0044_full_text_search.py

diff --git a/api/config/settings/common.py b/api/config/settings/common.py
index 307f09329..2fb7b496c 100644
--- a/api/config/settings/common.py
+++ b/api/config/settings/common.py
@@ -928,4 +928,3 @@ MODERATION_EMAIL_NOTIFICATIONS_ENABLED = env.bool(
 # Delay in days after signup before we show the "support us" messages
 INSTANCE_SUPPORT_MESSAGE_DELAY = env.int("INSTANCE_SUPPORT_MESSAGE_DELAY", default=15)
 FUNKWHALE_SUPPORT_MESSAGE_DELAY = env.int("FUNKWHALE_SUPPORT_MESSAGE_DELAY", default=15)
-USE_FULL_TEXT_SEARCH = env.bool("USE_FULL_TEXT_SEARCH", default=False)
diff --git a/api/funkwhale_api/common/search.py b/api/funkwhale_api/common/search.py
index b43342594..4e42fd346 100644
--- a/api/funkwhale_api/common/search.py
+++ b/api/funkwhale_api/common/search.py
@@ -1,6 +1,5 @@
 import re
 
-from django.contrib.postgres.search import SearchQuery
 from django.db.models import Q
 
 
@@ -57,17 +56,6 @@ def get_query(query_string, search_fields):
     return query
 
 
-def get_fts_query(query_string):
-    if not query_string.startswith('"') and not query_string.endswith('"'):
-        parts = query_string.split(" ")
-        parts = ["{}:*".format(p) for p in parts if p]
-        if not parts:
-            return Q(pk=None)
-
-        query_string = "&".join(parts)
-    return Q(body_text=SearchQuery(query_string, search_type="raw"))
-
-
 def filter_tokens(tokens, valid):
     return [t for t in tokens if t["key"] in valid]
 
diff --git a/api/funkwhale_api/music/migrations/0044_full_text_search.py b/api/funkwhale_api/music/migrations/0044_full_text_search.py
deleted file mode 100644
index e44df90d9..000000000
--- a/api/funkwhale_api/music/migrations/0044_full_text_search.py
+++ /dev/null
@@ -1,109 +0,0 @@
-# Generated by Django 2.2.7 on 2019-12-16 15:06
-
-import django.contrib.postgres.search
-import django.contrib.postgres.indexes
-from django.db import migrations, models
-import django.db.models.deletion
-from django.db import connection
-
-FIELDS = {
-    "music.Artist": {
-        "fields": [
-            'name',
-        ],
-        "trigger_name": "music_artist_update_body_text"
-    },
-    "music.Track": {
-        "fields": ['title', 'copyright'],
-        "trigger_name": "music_track_update_body_text"
-    },
-    "music.Album": {
-        "fields": ['title'],
-        "trigger_name": "music_album_update_body_text"
-    },
-}
-
-def populate_body_text(apps, schema_editor):
-    for label, search_config in FIELDS.items():
-        model = apps.get_model(*label.split('.'))
-        print('Populating search index for {}…'.format(model.__name__))
-        vector = django.contrib.postgres.search.SearchVector(*search_config['fields'])
-        model.objects.update(body_text=vector)
-
-def rewind(apps, schema_editor):
-    pass
-
-def setup_triggers(apps, schema_editor):
-    cursor = connection.cursor()
-    for label, search_config in FIELDS.items():
-        model = apps.get_model(*label.split('.'))
-        table = model._meta.db_table
-        print('Creating database trigger {} on {}…'.format(search_config['trigger_name'], table))
-        sql = """
-            CREATE TRIGGER {trigger_name}
-                BEFORE INSERT OR UPDATE
-                ON {table}
-                FOR EACH ROW
-                EXECUTE PROCEDURE
-                    tsvector_update_trigger(body_text, 'pg_catalog.english', {fields})
-        """.format(
-            trigger_name=search_config['trigger_name'],
-            table=table,
-            fields=', '.join(search_config['fields']),
-        )
-        print(sql)
-        cursor.execute(sql)
-
-def rewind_triggers(apps, schema_editor):
-    cursor = connection.cursor()
-    for label, search_config in FIELDS.items():
-        model = apps.get_model(*label.split('.'))
-        table = model._meta.db_table
-        print('Dropping database trigger {} on {}…'.format(search_config['trigger_name'], table))
-        sql = """
-            DROP TRIGGER IF EXISTS {trigger_name} ON {table}
-        """.format(
-            trigger_name=search_config['trigger_name'],
-            table=table,
-        )
-
-        cursor.execute(sql)
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        ('music', '0043_album_cover_attachment'),
-    ]
-
-    operations = [
-        migrations.AddField(
-            model_name='album',
-            name='body_text',
-            field=django.contrib.postgres.search.SearchVectorField(blank=True),
-        ),
-        migrations.AddField(
-            model_name='artist',
-            name='body_text',
-            field=django.contrib.postgres.search.SearchVectorField(blank=True),
-        ),
-        migrations.AddField(
-            model_name='track',
-            name='body_text',
-            field=django.contrib.postgres.search.SearchVectorField(blank=True),
-        ),
-        migrations.AddIndex(
-            model_name='album',
-            index=django.contrib.postgres.indexes.GinIndex(fields=['body_text'], name='music_album_body_te_0ec97a_gin'),
-        ),
-        migrations.AddIndex(
-            model_name='artist',
-            index=django.contrib.postgres.indexes.GinIndex(fields=['body_text'], name='music_artis_body_te_5c408d_gin'),
-        ),
-        migrations.AddIndex(
-            model_name='track',
-            index=django.contrib.postgres.indexes.GinIndex(fields=['body_text'], name='music_track_body_te_da0a66_gin'),
-        ),
-
-        migrations.RunPython(setup_triggers, rewind_triggers),
-        migrations.RunPython(populate_body_text, rewind),
-    ]
diff --git a/api/funkwhale_api/music/models.py b/api/funkwhale_api/music/models.py
index 3f8c0ffdf..f53e8e463 100644
--- a/api/funkwhale_api/music/models.py
+++ b/api/funkwhale_api/music/models.py
@@ -11,8 +11,6 @@ import pydub
 from django.conf import settings
 from django.contrib.contenttypes.fields import GenericRelation
 from django.contrib.postgres.fields import JSONField
-from django.contrib.postgres.search import SearchVectorField
-from django.contrib.postgres.indexes import GinIndex
 from django.core.exceptions import ObjectDoesNotExist
 from django.core.files.base import ContentFile
 from django.core.serializers.json import DjangoJSONEncoder
@@ -21,6 +19,7 @@ from django.db.models.signals import post_save, pre_save
 from django.dispatch import receiver
 from django.urls import reverse
 from django.utils import timezone
+
 from versatileimagefield.fields import VersatileImageField
 
 from funkwhale_api import musicbrainz
@@ -57,14 +56,10 @@ class APIModelMixin(models.Model):
     api_includes = []
     creation_date = models.DateTimeField(default=timezone.now, db_index=True)
     import_hooks = []
-    body_text = SearchVectorField(blank=True)
 
     class Meta:
         abstract = True
         ordering = ["-creation_date"]
-        indexes = [
-            GinIndex(fields=["body_text"]),
-        ]
 
     @classmethod
     def get_or_create_from_api(cls, mbid):
@@ -529,9 +524,6 @@ class Track(APIModelMixin):
 
     class Meta:
         ordering = ["album", "disc_number", "position"]
-        indexes = [
-            GinIndex(fields=["body_text"]),
-        ]
 
     def __str__(self):
         return self.title
diff --git a/api/funkwhale_api/music/utils.py b/api/funkwhale_api/music/utils.py
index b728549d7..09c8cbd12 100644
--- a/api/funkwhale_api/music/utils.py
+++ b/api/funkwhale_api/music/utils.py
@@ -4,11 +4,7 @@ import magic
 import mutagen
 import pydub
 
-from funkwhale_api.common.search import (
-    normalize_query,
-    get_query,
-    get_fts_query,
-)  # noqa
+from funkwhale_api.common.search import normalize_query, get_query  # noqa
 
 
 def guess_mimetype(f):
diff --git a/api/funkwhale_api/music/views.py b/api/funkwhale_api/music/views.py
index 3b692cb4f..57d009e99 100644
--- a/api/funkwhale_api/music/views.py
+++ b/api/funkwhale_api/music/views.py
@@ -629,10 +629,7 @@ class Search(views.APIView):
             "album__title__unaccent",
             "artist__name__unaccent",
         ]
-        if settings.USE_FULL_TEXT_SEARCH:
-            query_obj = utils.get_fts_query(query)
-        else:
-            query_obj = utils.get_query(query, search_fields)
+        query_obj = utils.get_query(query, search_fields)
         qs = (
             models.Track.objects.all()
             .filter(query_obj)
@@ -642,10 +639,7 @@ class Search(views.APIView):
 
     def get_albums(self, query):
         search_fields = ["mbid", "title__unaccent", "artist__name__unaccent"]
-        if settings.USE_FULL_TEXT_SEARCH:
-            query_obj = utils.get_fts_query(query)
-        else:
-            query_obj = utils.get_query(query, search_fields)
+        query_obj = utils.get_query(query, search_fields)
         qs = (
             models.Album.objects.all()
             .filter(query_obj)
@@ -655,10 +649,7 @@ class Search(views.APIView):
 
     def get_artists(self, query):
         search_fields = ["mbid", "name__unaccent"]
-        if settings.USE_FULL_TEXT_SEARCH:
-            query_obj = utils.get_fts_query(query)
-        else:
-            query_obj = utils.get_query(query, search_fields)
+        query_obj = utils.get_query(query, search_fields)
         qs = models.Artist.objects.all().filter(query_obj).with_albums()
         return common_utils.order_for_search(qs, "name")[: self.max_results]
 
-- 
GitLab