prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  Search: Make update_index update all backends
  Currently, it only updates the default backend. It should update all search backends.
  
  
  </issue>
  <code>
  [start of wagtail/wagtailsearch/management/commands/update_index.py]
  1 from django.core.management.base import BaseCommand
  2 from django.db import models
  3 
  4 from wagtail.wagtailsearch import Indexed, get_search_backend
  5 
  6 
  7 class Command(BaseCommand):
  8     def handle(self, **options):
  9         # Print info
  10         self.stdout.write("Getting object list")
  11 
  12         # Get list of indexed models
  13         indexed_models = [model for model in models.get_models() if issubclass(model, Indexed)]
  14 
  15         # Object set
  16         object_set = {}
  17 
  18         # Add all objects to object set and detect any duplicates
  19         # Duplicates are caused when both a model and a derived model are indexed
  20         # Eg, if BlogPost inherits from Page and both of these models are indexed
  21         # If we were to add all objects from both models into the index, all the BlogPosts will have two entries
  22         for model in indexed_models:
  23             # Get toplevel content type
  24             toplevel_content_type = model.indexed_get_toplevel_content_type()
  25 
  26             # Loop through objects
  27             for obj in model.get_indexed_objects():
  28                 # Get key for this object
  29                 key = toplevel_content_type + ':' + str(obj.pk)
  30 
  31                 # Check if this key already exists
  32                 if key in object_set:
  33                     # Conflict, work out who should get this space
  34                     # The object with the longest content type string gets the space
  35                     # Eg, "wagtailcore.Page-myapp.BlogPost" kicks out "wagtailcore.Page"
  36                     if len(obj.indexed_get_content_type()) > len(object_set[key].indexed_get_content_type()):
  37                         # Take the spot
  38                         object_set[key] = obj
  39                 else:
  40                     # Space free, take it
  41                     object_set[key] = obj
  42 
  43         # Search backend
  44         if 'backend' in options:
  45             s = options['backend']
  46         else:
  47             s = get_search_backend()
  48 
  49         # Reset the index
  50         self.stdout.write("Reseting index")
  51         s.reset_index()
  52 
  53         # Add types
  54         self.stdout.write("Adding types")
  55         for model in indexed_models:
  56             s.add_type(model)
  57 
  58         # Add objects to index
  59         self.stdout.write("Adding objects")
  60         for result in s.add_bulk(object_set.values()):
  61             self.stdout.write(result[0] + ' ' + str(result[1]))
  62 
  63         # Refresh index
  64         self.stdout.write("Refreshing index")
  65         s.refresh_index()
  66
  [end of wagtail/wagtailsearch/management/commands/update_index.py]
  </code>
  
  I need you to solve this issue by generating a single patch file that I can apply directly to this repository using git apply. Please respond with a single patch file in the following format.
  <patch>
  diff --git a/file.py b/file.py
  --- a/file.py
  +++ b/file.py
  @@ -1,27 +1,35 @@
   def euclidean(a, b):
  -    while b:
  -        a, b = b, a % b
  -    return a
  +    if b == 0:
  +        return a
  +    return euclidean(b, a % b)
   
   
   def bresenham(x0, y0, x1, y1):
       points = []
       dx = abs(x1 - x0)
       dy = abs(y1 - y0)
  -    sx = 1 if x0 < x1 else -1
  -    sy = 1 if y0 < y1 else -1
  -    err = dx - dy
  +    x, y = x0, y0
  +    sx = -1 if x0 > x1 else 1
  +    sy = -1 if y0 > y1 else 1
   
  -    while True:
  -        points.append((x0, y0))
  -        if x0 == x1 and y0 == y1:
  -            break
  -        e2 = 2 * err
  -        if e2 > -dy:
  -            err -= dy
  -            x0 += sx
  -        if e2 < dx:
  -            err += dx
  -            y0 += sy
  +    if dx > dy:
  +        err = dx / 2.0
  +        while x != x1:
  +            points.append((x, y))
  +            err -= dy
  +            if err < 0:
  +                y += sy
  +                err += dx
  +            x += sx
  +    else:
  +        err = dy / 2.0
  +        while y != y1:
  +            points.append((x, y))
  +            err -= dx
  +            if err < 0:
  +                x += sx
  +                err += dy
  +            y += sy
  +
  +    points.append((x, y))
       return points
  
  </patch>
golden_diff: diff --git a/wagtail/wagtailsearch/management/commands/update_index.py b/wagtail/wagtailsearch/management/commands/update_index.py
  --- a/wagtail/wagtailsearch/management/commands/update_index.py
  +++ b/wagtail/wagtailsearch/management/commands/update_index.py
  @@ -1,11 +1,22 @@
  +from optparse import make_option
  +
   from django.core.management.base import BaseCommand
   from django.db import models
  +from django.conf import settings
   
   from wagtail.wagtailsearch import Indexed, get_search_backend
   
   
  +def get_search_backends():
  +    if hasattr(settings, 'WAGTAILSEARCH_BACKENDS'):
  +        for backend in settings.WAGTAILSEARCH_BACKENDS.keys():
  +            yield backend, get_search_backend(backend)
  +    else:
  +        yield 'default', get_search_backend('default')
  +
  +
   class Command(BaseCommand):
  -    def handle(self, **options):
  +    def get_object_list(self):
           # Print info
           self.stdout.write("Getting object list")
   
  @@ -40,26 +51,51 @@
                       # Space free, take it
                       object_set[key] = obj
   
  -        # Search backend
  -        if 'backend' in options:
  -            s = options['backend']
  -        else:
  -            s = get_search_backend()
  +        return indexed_models, object_set.values()
  +
  +    def update_backend(self, backend, models, object_list, backend_name=''):
  +        # Print info
  +        self.stdout.write("Updating backend: " + backend_name)
  +
  +        # Get backend
  +        if backend is None:
  +            backend = get_search_backend(backend_name)
   
           # Reset the index
  -        self.stdout.write("Reseting index")
  -        s.reset_index()
  +        self.stdout.write(backend_name + ": Reseting index")
  +        backend.reset_index()
   
           # Add types
  -        self.stdout.write("Adding types")
  -        for model in indexed_models:
  -            s.add_type(model)
  +        self.stdout.write(backend_name + ": Adding types")
  +        for model in models:
  +            backend.add_type(model)
   
           # Add objects to index
  -        self.stdout.write("Adding objects")
  -        for result in s.add_bulk(object_set.values()):
  +        self.stdout.write(backend_name + ": Adding objects")
  +        for result in backend.add_bulk(object_list):
               self.stdout.write(result[0] + ' ' + str(result[1]))
   
           # Refresh index
  -        self.stdout.write("Refreshing index")
  -        s.refresh_index()
  +        self.stdout.write(backend_name + ": Refreshing index")
  +        backend.refresh_index()
  +
  +    option_list = BaseCommand.option_list + (
  +        make_option('--backend',
  +            action='store',
  +            dest='backend_name',
  +            default=False,
  +            help="Specify a backend to update",
  +        ),
  +    )
  +
  +    def handle(self, **options):
  +        # Get object list
  +        models, object_list = self.get_object_list()
  +
  +        # Update backends
  +        if 'backend_name' in options:
  +            backend = dict(get_search_backends())[options['backend_name']]
  +            self.update_backend(backend, models, object_list, backend_name=options['backend_name'])
  +        else:
  +            for backend_name, backend in get_search_backends():
  +                self.update_backend(backend, models, object_list, backend_name=backend_name)
  
verification_info: {"golden_diff": "diff --git a/wagtail/wagtailsearch/management/commands/update_index.py b/wagtail/wagtailsearch/management/commands/update_index.py\n--- a/wagtail/wagtailsearch/management/commands/update_index.py\n+++ b/wagtail/wagtailsearch/management/commands/update_index.py\n@@ -1,11 +1,22 @@\n+from optparse import make_option\n+\n from django.core.management.base import BaseCommand\n from django.db import models\n+from django.conf import settings\n \n from wagtail.wagtailsearch import Indexed, get_search_backend\n \n \n+def get_search_backends():\n+    if hasattr(settings, 'WAGTAILSEARCH_BACKENDS'):\n+        for backend in settings.WAGTAILSEARCH_BACKENDS.keys():\n+            yield backend, get_search_backend(backend)\n+    else:\n+        yield 'default', get_search_backend('default')\n+\n+\n class Command(BaseCommand):\n-    def handle(self, **options):\n+    def get_object_list(self):\n         # Print info\n         self.stdout.write(\"Getting object list\")\n \n@@ -40,26 +51,51 @@\n                     # Space free, take it\n                     object_set[key] = obj\n \n-        # Search backend\n-        if 'backend' in options:\n-            s = options['backend']\n-        else:\n-            s = get_search_backend()\n+        return indexed_models, object_set.values()\n+\n+    def update_backend(self, backend, models, object_list, backend_name=''):\n+        # Print info\n+        self.stdout.write(\"Updating backend: \" + backend_name)\n+\n+        # Get backend\n+        if backend is None:\n+            backend = get_search_backend(backend_name)\n \n         # Reset the index\n-        self.stdout.write(\"Reseting index\")\n-        s.reset_index()\n+        self.stdout.write(backend_name + \": Reseting index\")\n+        backend.reset_index()\n \n         # Add types\n-        self.stdout.write(\"Adding types\")\n-        for model in indexed_models:\n-            s.add_type(model)\n+        self.stdout.write(backend_name + \": Adding types\")\n+        for model in models:\n+            backend.add_type(model)\n \n         # Add objects to index\n-        self.stdout.write(\"Adding objects\")\n-        for result in s.add_bulk(object_set.values()):\n+        self.stdout.write(backend_name + \": Adding objects\")\n+        for result in backend.add_bulk(object_list):\n             self.stdout.write(result[0] + ' ' + str(result[1]))\n \n         # Refresh index\n-        self.stdout.write(\"Refreshing index\")\n-        s.refresh_index()\n+        self.stdout.write(backend_name + \": Refreshing index\")\n+        backend.refresh_index()\n+\n+    option_list = BaseCommand.option_list + (\n+        make_option('--backend',\n+            action='store',\n+            dest='backend_name',\n+            default=False,\n+            help=\"Specify a backend to update\",\n+        ),\n+    )\n+\n+    def handle(self, **options):\n+        # Get object list\n+        models, object_list = self.get_object_list()\n+\n+        # Update backends\n+        if 'backend_name' in options:\n+            backend = dict(get_search_backends())[options['backend_name']]\n+            self.update_backend(backend, models, object_list, backend_name=options['backend_name'])\n+        else:\n+            for backend_name, backend in get_search_backends():\n+                self.update_backend(backend, models, object_list, backend_name=backend_name)\n", "issue": "Search: Make update_index update all backends\nCurrently, it only updates the default backend. It should update all search backends.\n\n", "before_files": [{"content": "from django.core.management.base import BaseCommand\nfrom django.db import models\n\nfrom wagtail.wagtailsearch import Indexed, get_search_backend\n\n\nclass Command(BaseCommand):\n    def handle(self, **options):\n        # Print info\n        self.stdout.write(\"Getting object list\")\n\n        # Get list of indexed models\n        indexed_models = [model for model in models.get_models() if issubclass(model, Indexed)]\n\n        # Object set\n        object_set = {}\n\n        # Add all objects to object set and detect any duplicates\n        # Duplicates are caused when both a model and a derived model are indexed\n        # Eg, if BlogPost inherits from Page and both of these models are indexed\n        # If we were to add all objects from both models into the index, all the BlogPosts will have two entries\n        for model in indexed_models:\n            # Get toplevel content type\n            toplevel_content_type = model.indexed_get_toplevel_content_type()\n\n            # Loop through objects\n            for obj in model.get_indexed_objects():\n                # Get key for this object\n                key = toplevel_content_type + ':' + str(obj.pk)\n\n                # Check if this key already exists\n                if key in object_set:\n                    # Conflict, work out who should get this space\n                    # The object with the longest content type string gets the space\n                    # Eg, \"wagtailcore.Page-myapp.BlogPost\" kicks out \"wagtailcore.Page\"\n                    if len(obj.indexed_get_content_type()) > len(object_set[key].indexed_get_content_type()):\n                        # Take the spot\n                        object_set[key] = obj\n                else:\n                    # Space free, take it\n                    object_set[key] = obj\n\n        # Search backend\n        if 'backend' in options:\n            s = options['backend']\n        else:\n            s = get_search_backend()\n\n        # Reset the index\n        self.stdout.write(\"Reseting index\")\n        s.reset_index()\n\n        # Add types\n        self.stdout.write(\"Adding types\")\n        for model in indexed_models:\n            s.add_type(model)\n\n        # Add objects to index\n        self.stdout.write(\"Adding objects\")\n        for result in s.add_bulk(object_set.values()):\n            self.stdout.write(result[0] + ' ' + str(result[1]))\n\n        # Refresh index\n        self.stdout.write(\"Refreshing index\")\n        s.refresh_index()\n", "path": "wagtail/wagtailsearch/management/commands/update_index.py"}]}