user topic: Add case insensitive UNIQUE constraint.

This will allow us to rely on the database to detect duplicate
`UserTopic`s (with the same `topic_name` with different cases)
and thus correctly throw IntegrityErrors when expected.
This is also important from a correctness point of view, since as
of now, when checking if topic is muted or requesting the backend for
muting a topic, the frontend does not check for case insensitivity.

There might exist duplicate UserTopics (in a case insensitive sense)
which need are removed before creating the new index.
The migration was tested manually using `./manage.py shell`.
This commit is contained in:
Abhijeet Prasad Bodas
2023-02-10 23:40:19 +05:30
committed by Tim Abbott
parent 9fde88796a
commit 80bf6b0777
2 changed files with 41 additions and 2 deletions

View File

@@ -43,7 +43,7 @@ from django.core.validators import MinLengthValidator, RegexValidator, URLValida
from django.db import models, transaction
from django.db.backends.base.base import BaseDatabaseWrapper
from django.db.models import CASCADE, Exists, F, OuterRef, Q, Sum
from django.db.models.functions import Upper
from django.db.models.functions import Lower, Upper
from django.db.models.query import QuerySet
from django.db.models.signals import post_delete, post_save, pre_delete
from django.db.models.sql.compiler import SQLCompiler
@@ -2648,7 +2648,14 @@ class UserTopic(models.Model):
visibility_policy = models.SmallIntegerField(choices=visibility_policy_choices, default=MUTED)
class Meta:
unique_together = ("user_profile", "stream", "topic_name")
constraints = [
models.UniqueConstraint(
"user_profile",
"stream",
Lower("topic_name"),
name="usertopic_case_insensitive_topic_uniq",
),
]
indexes = [
models.Index("stream", Upper("topic_name"), name="zerver_mutedtopic_stream_topic"),