Simplify bulk_remove_subscriptions().

We extract get_bulk_stream_subscriber_info() from this
function to remove some of the complexity.  Also, in that
new function we avoid a hop to the database by querying
on stream ids instead of recipient ids.  The query that
gets changed here does require a join to the recipient
table (to get the stream id), so it's a little bit of a
tradeoff.
This commit is contained in:
Steve Howell
2017-10-29 12:19:57 -07:00
committed by Tim Abbott
parent 48d13257b6
commit faba34dae4
3 changed files with 78 additions and 26 deletions

View File

@@ -1,8 +1,10 @@
from typing import List
from typing import Dict, List, Tuple
from mypy_extensions import TypedDict
from django.db.models.query import QuerySet
from zerver.models import (
Recipient,
Stream,
Subscription,
UserProfile,
)
@@ -37,6 +39,36 @@ def get_stream_subscriptions_for_users(user_profiles):
recipient__type=Recipient.STREAM,
)
SubInfo = TypedDict('SubInfo', {
'sub': Subscription,
'stream': Stream,
})
def get_bulk_stream_subscriber_info(user_profiles, stream_dict):
# type: (List[UserProfile], Dict[int, Stream]) -> Dict[int, List[Tuple[Subscription, Stream]]]
stream_ids = stream_dict.keys()
result = {
user_profile.id: []
for user_profile in user_profiles
} # type: Dict[int, List[Tuple[Subscription, Stream]]]
subs = Subscription.objects.filter(
user_profile__in=user_profiles,
recipient__type=Recipient.STREAM,
recipient__type_id__in=stream_ids,
active=True,
).select_related('user_profile', 'recipient')
for sub in subs:
user_profile_id = sub.user_profile_id
stream_id = sub.recipient.type_id
stream = stream_dict[stream_id]
result[user_profile_id].append((sub, stream))
return result
def num_subscribers_for_stream_id(stream_id):
# type: (int) -> int
return get_active_subscriptions_for_stream_id(stream_id).filter(