Browse Source

Added django.db.backends.utils.names_digest() to remove redundant code.

Jon Dufresne 6 years ago
parent
commit
0bf7b25f8f
3 changed files with 16 additions and 31 deletions
  1. 2 14
      django/db/backends/base/schema.py
  2. 12 1
      django/db/backends/utils.py
  3. 2 16
      django/db/models/indexes.py

+ 2 - 14
django/db/backends/base/schema.py

@@ -1,11 +1,10 @@
-import hashlib
 import logging
 from datetime import datetime
 
 from django.db.backends.ddl_references import (
     Columns, ForeignKeyName, IndexName, Statement, Table,
 )
-from django.db.backends.utils import split_identifier
+from django.db.backends.utils import names_digest, split_identifier
 from django.db.models import Index
 from django.db.transaction import TransactionManagementError, atomic
 from django.utils import timezone
@@ -135,17 +134,6 @@ class BaseDatabaseSchemaEditor:
     def quote_name(self, name):
         return self.connection.ops.quote_name(name)
 
-    @classmethod
-    def _digest(cls, *args):
-        """
-        Generate a 32-bit digest of a set of arguments that can be used to
-        shorten identifying names.
-        """
-        h = hashlib.md5()
-        for arg in args:
-            h.update(arg.encode())
-        return h.hexdigest()[:8]
-
     # Field <-> database mapping functions
 
     def column_sql(self, model, field, include_default=False):
@@ -885,7 +873,7 @@ class BaseDatabaseSchemaEditor:
         and a unique digest and suffix.
         """
         _, table_name = split_identifier(table_name)
-        hash_suffix_part = '%s%s' % (self._digest(table_name, *column_names), suffix)
+        hash_suffix_part = '%s%s' % (names_digest(table_name, *column_names, length=8), suffix)
         max_length = self.connection.ops.max_name_length() or 200
         # If everything fits into max_length, use that name.
         index_name = '%s_%s_%s' % (table_name, '_'.join(column_names), hash_suffix_part)

+ 12 - 1
django/db/backends/utils.py

@@ -213,10 +213,21 @@ def truncate_name(identifier, length=None, hash_len=4):
     if length is None or len(name) <= length:
         return identifier
 
-    digest = hashlib.md5(name.encode()).hexdigest()[:hash_len]
+    digest = names_digest(name, length=hash_len)
     return '%s%s%s' % ('%s"."' % namespace if namespace else '', name[:length - hash_len], digest)
 
 
+def names_digest(*args, length):
+    """
+    Generate a 32-bit digest of a set of arguments that can be used to shorten
+    identifying names.
+    """
+    h = hashlib.md5()
+    for arg in args:
+        h.update(arg.encode())
+    return h.hexdigest()[:length]
+
+
 def format_number(value, max_digits, decimal_places):
     """
     Format a number into a string with the requisite number of digits and

+ 2 - 16
django/db/models/indexes.py

@@ -1,7 +1,4 @@
-import hashlib
-
-from django.db.backends.utils import split_identifier
-from django.utils.encoding import force_bytes
+from django.db.backends.utils import names_digest, split_identifier
 
 __all__ = ['Index']
 
@@ -81,17 +78,6 @@ class Index:
         _, _, kwargs = self.deconstruct()
         return self.__class__(**kwargs)
 
-    @staticmethod
-    def _hash_generator(*args):
-        """
-        Generate a 32-bit digest of a set of arguments that can be used to
-        shorten identifying names.
-        """
-        h = hashlib.md5()
-        for arg in args:
-            h.update(force_bytes(arg))
-        return h.hexdigest()[:6]
-
     def set_name_with_model(self, model):
         """
         Generate a unique name for the index.
@@ -112,7 +98,7 @@ class Index:
         self.name = '%s_%s_%s' % (
             table_name[:11],
             column_names[0][:7],
-            '%s_%s' % (self._hash_generator(*hash_data), self.suffix),
+            '%s_%s' % (names_digest(*hash_data, length=6), self.suffix),
         )
         assert len(self.name) <= self.max_name_length, (
             'Index too long for multiple database support. Is self.suffix '