Repository: wagtail/wagtail

Issue:
Remove (or un-deprecate) ElasticsearchSearchBackend methods deprecated from 2.0
As per https://github.com/wagtail/wagtail/pull/3975#issuecomment-389961302 - these methods are scheduled to be removed in 2.2, but it's not clear to me what's really meant to be happening to them (since it doesn't make sense to remove the implementations from ElasticsearchSearchBackend while they're still a defined (and actively-used) part of the search backend API).

For now (#4551) I've left them in place, along with the definition of `RemovedInWagtail22Warning` in `wagtail.utils.deprecation`, but these will need to be dealt with before 2.2 is released.


Discussion:
I've replied to your original comment here: https://github.com/wagtail/wagtail/pull/3975#issuecomment-392711064


In summary, I now think we should keep these methods but move their implementations to ``BaseSearchBackend`` and add a dummy index class for the database backend so they don't crash there.

Resolving patch:
diff --git a/wagtail/search/backends/base.py b/wagtail/search/backends/base.py
--- a/wagtail/search/backends/base.py
+++ b/wagtail/search/backends/base.py
@@ -4,7 +4,7 @@
 from django.db.models.query import QuerySet
 from django.db.models.sql.where import SubqueryConstraint, WhereNode
 
-from wagtail.search.index import class_is_indexed
+from wagtail.search.index import class_is_indexed, get_indexed_models
 from wagtail.search.query import MATCH_ALL, PlainText
 
 
@@ -272,6 +272,28 @@ def _do_count(self):
         return 0
 
 
+class NullIndex:
+    """
+    Index class that provides do-nothing implementations of the indexing operations required by
+    BaseSearchBackend. Use this for search backends that do not maintain an index, such as the
+    database backend.
+    """
+    def add_model(self, model):
+        pass
+
+    def refresh(self):
+        pass
+
+    def add_item(self, item):
+        pass
+
+    def add_items(self, model, items):
+        pass
+
+    def delete_item(self, item):
+        pass
+
+
 class BaseSearchBackend:
     query_compiler_class = None
     autocomplete_query_compiler_class = None
@@ -282,7 +304,7 @@ def __init__(self, params):
         pass
 
     def get_index_for_model(self, model):
-        return None
+        return NullIndex()
 
     def get_rebuilder(self):
         return None
@@ -291,19 +313,24 @@ def reset_index(self):
         raise NotImplementedError
 
     def add_type(self, model):
-        raise NotImplementedError
+        self.get_index_for_model(model).add_model(model)
 
     def refresh_index(self):
-        raise NotImplementedError
+        refreshed_indexes = []
+        for model in get_indexed_models:
+            index = self.get_index_for_model(model)
+            if index not in refreshed_indexes:
+                index.refresh()
+                refreshed_indexes.append(index)
 
     def add(self, obj):
-        raise NotImplementedError
+        self.get_index_for_model(type(obj)).add_item(obj)
 
     def add_bulk(self, model, obj_list):
-        raise NotImplementedError
+        self.get_index_for_model(model).add_items(model, obj_list)
 
     def delete(self, obj):
-        raise NotImplementedError
+        self.get_index_for_model(type(obj)).delete_item(obj)
 
     def _search(self, query_compiler_class, query, model_or_queryset, **kwargs):
         # Find model/queryset
diff --git a/wagtail/search/backends/elasticsearch2.py b/wagtail/search/backends/elasticsearch2.py
--- a/wagtail/search/backends/elasticsearch2.py
+++ b/wagtail/search/backends/elasticsearch2.py
@@ -1,6 +1,5 @@
 import copy
 import json
-import warnings
 from collections import OrderedDict
 from urllib.parse import urlparse
 
@@ -16,7 +15,6 @@
 from wagtail.search.index import (
     AutocompleteField, FilterField, Indexed, RelatedFields, SearchField, class_is_indexed)
 from wagtail.search.query import And, Boost, MatchAll, Not, Or, PlainText
-from wagtail.utils.deprecation import RemovedInWagtail22Warning
 from wagtail.utils.utils import deep_update
 
 
@@ -1100,50 +1098,5 @@ def reset_index(self):
         # Use the rebuilder to reset the index
         self.get_rebuilder().reset_index()
 
-    def add_type(self, model):
-        warnings.warn(
-            "The `backend.add_type(model)` method is deprecated. "
-            "Please use `backend.get_index_for_model(model).add_model(model)` instead.",
-            category=RemovedInWagtail22Warning
-        )
-
-        self.get_index_for_model(model).add_model(model)
-
-    def refresh_index(self):
-        warnings.warn(
-            "The `backend.refresh_index()` method is deprecated. "
-            "Please use `backend.get_index_for_model(model).refresh()` for each model instead.",
-            category=RemovedInWagtail22Warning
-        )
-
-        self.get_index().refresh()
-
-    def add(self, obj):
-        warnings.warn(
-            "The `backend.add(obj)` method is deprecated. "
-            "Please use `backend.get_index_for_model(type(obj)).add_item(obj)` instead.",
-            category=RemovedInWagtail22Warning
-        )
-
-        self.get_index_for_model(type(obj)).add_item(obj)
-
-    def add_bulk(self, model, obj_list):
-        warnings.warn(
-            "The `backend.add_bulk(model, obj_list)` method is deprecated. "
-            "Please use `self.get_index_for_model(model).add_items(model, obj_list)` instead.",
-            category=RemovedInWagtail22Warning
-        )
-
-        self.get_index_for_model(model).add_items(model, obj_list)
-
-    def delete(self, obj):
-        warnings.warn(
-            "The `backend.delete(obj)` method is deprecated. "
-            "Please use `backend.get_index_for_model(type(obj)).delete_item(obj)` instead.",
-            category=RemovedInWagtail22Warning
-        )
-
-        self.get_index_for_model(type(obj)).delete_item(obj)
-
 
 SearchBackend = Elasticsearch2SearchBackend
diff --git a/wagtail/utils/deprecation.py b/wagtail/utils/deprecation.py
--- a/wagtail/utils/deprecation.py
+++ b/wagtail/utils/deprecation.py
@@ -1,7 +1,3 @@
-class RemovedInWagtail22Warning(DeprecationWarning):
-    pass
-
-
 class RemovedInWagtail23Warning(DeprecationWarning):
     pass
 


Test patch:
diff --git a/wagtail/search/tests/test_db_backend.py b/wagtail/search/tests/test_db_backend.py
--- a/wagtail/search/tests/test_db_backend.py
+++ b/wagtail/search/tests/test_db_backend.py
@@ -33,11 +33,6 @@ def test_annotate_score_with_slice(self):
     def test_search_boosting_on_related_fields(self):
         super().test_search_boosting_on_related_fields()
 
-    # Doesn't support ranking
-    @unittest.expectedFailure
-    def test_same_rank_pages(self):
-        super(TestDBBackend, self).test_same_rank_pages()
-
     # Doesn't support searching specific fields
     @unittest.expectedFailure
     def test_search_child_class_field_from_parent(self):