Only return unread notifications

Make get_unread_push_actions_for_user_in_range only return unread event actions, being more true to its name. Done in two separate sql queries to get actions after a read receipt and those in a room wiht no receipt at all. SQL queries by Erik.
This commit is contained in:
David Baker 2016-04-13 14:16:45 +01:00
parent 65141161f6
commit 54d08c8868

View File

@ -116,26 +116,67 @@ class EventPushActionsStore(SQLBaseStore):
def get_unread_push_actions_for_user_in_range(self, user_id, def get_unread_push_actions_for_user_in_range(self, user_id,
min_stream_ordering, min_stream_ordering,
max_stream_ordering=None): max_stream_ordering=None):
def f(txn): def get_after_receipt(txn):
sql = ( sql = (
"SELECT event_id, stream_ordering, actions" "SELECT ep.event_id, ep.stream_ordering, ep.actions "
" FROM event_push_actions" "FROM event_push_actions AS ep, ("
" WHERE user_id = ? AND stream_ordering > ?" " SELECT room_id, user_id,"
" max(topological_ordering) as topological_ordering,"
" max(stream_ordering) as stream_ordering"
" FROM events"
" NATURAL JOIN receipts_linearized WHERE receipt_type = 'm.read'"
" GROUP BY room_id, user_id"
") AS rl "
"WHERE"
" ep.room_id = rl.room_id"
" AND ("
" ep.topological_ordering > rl.topological_ordering"
" OR ("
" ep.topological_ordering = rl.topological_ordering"
" AND ep.stream_ordering > ?"
" )"
" )"
" AND ep.user_id = ?"
" AND ep.user_id = rl.user_id"
) )
args = [user_id, min_stream_ordering] args = [min_stream_ordering, user_id]
if max_stream_ordering is not None: if max_stream_ordering is not None:
sql += " AND stream_ordering <= ?" sql += " AND ep.stream_ordering <= ?"
args.append(max_stream_ordering) args.append(max_stream_ordering)
sql += " ORDER BY stream_ordering ASC" sql += " ORDER BY ep.stream_ordering ASC"
txn.execute(sql, args) txn.execute(sql, args)
return txn.fetchall() return txn.fetchall()
ret = yield self.runInteraction("get_unread_push_actions_for_user_in_range", f) after_read_receipt = yield self.runInteraction(
"get_unread_push_actions_for_user_in_range", get_after_receipt
)
def get_no_receipt(txn):
sql = (
"SELECT ep.event_id, ep.stream_ordering, ep.actions "
"FROM event_push_actions AS ep "
"WHERE ep.room_id not in ("
" SELECT room_id FROM events NATURAL JOIN receipts_linearized"
" WHERE receipt_type = 'm.read' AND user_id = ? "
" GROUP BY room_id"
") AND ep.user_id = ? AND ep.stream_ordering > ?"
)
args = [user_id, user_id, min_stream_ordering]
if max_stream_ordering is not None:
sql += " AND ep.stream_ordering <= ?"
args.append(max_stream_ordering)
sql += " ORDER BY ep.stream_ordering ASC"
txn.execute(sql, args)
return txn.fetchall()
no_read_receipt = yield self.runInteraction(
"get_unread_push_actions_for_user_in_range", get_no_receipt
)
defer.returnValue([ defer.returnValue([
{ {
"event_id": row[0], "event_id": row[0],
"stream_ordering": row[1], "stream_ordering": row[1],
"actions": json.loads(row[2]), "actions": json.loads(row[2]),
} for row in ret } for row in after_read_receipt+no_read_receipt
]) ])
@defer.inlineCallbacks @defer.inlineCallbacks