mirror of
https://github.com/zulip/zulip.git
synced 2025-11-04 14:03:30 +00:00
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:
committed by
Tim Abbott
parent
9fde88796a
commit
80bf6b0777
@@ -0,0 +1,32 @@
|
||||
# Generated by Django 4.1.6 on 2023-02-11 05:16
|
||||
|
||||
import django.db.models.functions.text
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
dependencies = [
|
||||
("zerver", "0428_remove_realm_email_address_visibility"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterUniqueTogether(
|
||||
name="usertopic",
|
||||
unique_together=set(),
|
||||
),
|
||||
# Before adding the constraint, remove any pre-existing duplicates from the table
|
||||
migrations.RunSQL(
|
||||
"""
|
||||
DELETE FROM zerver_usertopic WHERE id NOT IN (SELECT max(id) FROM zerver_usertopic GROUP BY (user_profile_id, stream_id, upper(topic_name::text)));
|
||||
"""
|
||||
),
|
||||
migrations.AddConstraint(
|
||||
model_name="usertopic",
|
||||
constraint=models.UniqueConstraint(
|
||||
models.F("user_profile"),
|
||||
models.F("stream"),
|
||||
django.db.models.functions.text.Lower("topic_name"),
|
||||
name="usertopic_case_insensitive_topic_uniq",
|
||||
),
|
||||
),
|
||||
]
|
||||
@@ -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"),
|
||||
|
||||
Reference in New Issue
Block a user