Development of an internal social media platform with personalised dashboards for students
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

indexes.py 3.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. from django.db.models import Index
  2. from django.utils.functional import cached_property
  3. __all__ = ['BrinIndex', 'GinIndex', 'GistIndex']
  4. class PostgresIndex(Index):
  5. @cached_property
  6. def max_name_length(self):
  7. # Allow an index name longer than 30 characters when the suffix is
  8. # longer than the usual 3 character limit. The 30 character limit for
  9. # cross-database compatibility isn't applicable to PostgreSQL-specific
  10. # indexes.
  11. return Index.max_name_length - len(Index.suffix) + len(self.suffix)
  12. def create_sql(self, model, schema_editor, using=''):
  13. statement = super().create_sql(model, schema_editor, using=' USING %s' % self.suffix)
  14. with_params = self.get_with_params()
  15. if with_params:
  16. statement.parts['extra'] = 'WITH (%s) %s' % (
  17. ', '.join(with_params),
  18. statement.parts['extra'],
  19. )
  20. return statement
  21. def get_with_params(self):
  22. return []
  23. class BrinIndex(PostgresIndex):
  24. suffix = 'brin'
  25. def __init__(self, *, pages_per_range=None, **kwargs):
  26. if pages_per_range is not None and pages_per_range <= 0:
  27. raise ValueError('pages_per_range must be None or a positive integer')
  28. self.pages_per_range = pages_per_range
  29. super().__init__(**kwargs)
  30. def deconstruct(self):
  31. path, args, kwargs = super().deconstruct()
  32. if self.pages_per_range is not None:
  33. kwargs['pages_per_range'] = self.pages_per_range
  34. return path, args, kwargs
  35. def get_with_params(self):
  36. with_params = []
  37. if self.pages_per_range is not None:
  38. with_params.append('pages_per_range = %d' % self.pages_per_range)
  39. return with_params
  40. class GinIndex(PostgresIndex):
  41. suffix = 'gin'
  42. def __init__(self, *, fastupdate=None, gin_pending_list_limit=None, **kwargs):
  43. self.fastupdate = fastupdate
  44. self.gin_pending_list_limit = gin_pending_list_limit
  45. super().__init__(**kwargs)
  46. def deconstruct(self):
  47. path, args, kwargs = super().deconstruct()
  48. if self.fastupdate is not None:
  49. kwargs['fastupdate'] = self.fastupdate
  50. if self.gin_pending_list_limit is not None:
  51. kwargs['gin_pending_list_limit'] = self.gin_pending_list_limit
  52. return path, args, kwargs
  53. def get_with_params(self):
  54. with_params = []
  55. if self.gin_pending_list_limit is not None:
  56. with_params.append('gin_pending_list_limit = %d' % self.gin_pending_list_limit)
  57. if self.fastupdate is not None:
  58. with_params.append('fastupdate = %s' % ('on' if self.fastupdate else 'off'))
  59. return with_params
  60. class GistIndex(PostgresIndex):
  61. suffix = 'gist'
  62. def __init__(self, *, buffering=None, fillfactor=None, **kwargs):
  63. self.buffering = buffering
  64. self.fillfactor = fillfactor
  65. super().__init__(**kwargs)
  66. def deconstruct(self):
  67. path, args, kwargs = super().deconstruct()
  68. if self.buffering is not None:
  69. kwargs['buffering'] = self.buffering
  70. if self.fillfactor is not None:
  71. kwargs['fillfactor'] = self.fillfactor
  72. return path, args, kwargs
  73. def get_with_params(self):
  74. with_params = []
  75. if self.buffering is not None:
  76. with_params.append('buffering = %s' % ('on' if self.buffering else 'off'))
  77. if self.fillfactor is not None:
  78. with_params.append('fillfactor = %d' % self.fillfactor)
  79. return with_params