mirror of
https://git.anonymousland.org/anonymousland/synapse.git
synced 2025-05-03 04:44:52 -04:00
Consolidate logic for parsing relations. (#12693)
Parse the `m.relates_to` event content field (which describes relations) in a single place, this is used during: * Event persistence. * Validation of the Client-Server API. * Fetching bundled aggregations. * Processing of push rules. Each of these separately implement the logic and each made slightly different assumptions about what was valid. Some had minor / potential bugs.
This commit is contained in:
parent
cde8af9a49
commit
86a515ccbf
7 changed files with 98 additions and 61 deletions
|
@ -36,8 +36,8 @@ from prometheus_client import Counter
|
|||
import synapse.metrics
|
||||
from synapse.api.constants import EventContentFields, EventTypes, RelationTypes
|
||||
from synapse.api.room_versions import RoomVersions
|
||||
from synapse.events import EventBase # noqa: F401
|
||||
from synapse.events.snapshot import EventContext # noqa: F401
|
||||
from synapse.events import EventBase, relation_from_event
|
||||
from synapse.events.snapshot import EventContext
|
||||
from synapse.storage._base import db_to_json, make_in_list_sql_clause
|
||||
from synapse.storage.database import (
|
||||
DatabasePool,
|
||||
|
@ -1807,52 +1807,45 @@ class PersistEventsStore:
|
|||
txn: The current database transaction.
|
||||
event: The event which might have relations.
|
||||
"""
|
||||
relation = event.content.get("m.relates_to")
|
||||
relation = relation_from_event(event)
|
||||
if not relation:
|
||||
# No relations
|
||||
# No relation, nothing to do.
|
||||
return
|
||||
|
||||
# Relations must have a type and parent event ID.
|
||||
rel_type = relation.get("rel_type")
|
||||
if not isinstance(rel_type, str):
|
||||
return
|
||||
|
||||
parent_id = relation.get("event_id")
|
||||
if not isinstance(parent_id, str):
|
||||
return
|
||||
|
||||
# Annotations have a key field.
|
||||
aggregation_key = None
|
||||
if rel_type == RelationTypes.ANNOTATION:
|
||||
aggregation_key = relation.get("key")
|
||||
|
||||
self.db_pool.simple_insert_txn(
|
||||
txn,
|
||||
table="event_relations",
|
||||
values={
|
||||
"event_id": event.event_id,
|
||||
"relates_to_id": parent_id,
|
||||
"relation_type": rel_type,
|
||||
"aggregation_key": aggregation_key,
|
||||
"relates_to_id": relation.parent_id,
|
||||
"relation_type": relation.rel_type,
|
||||
"aggregation_key": relation.aggregation_key,
|
||||
},
|
||||
)
|
||||
|
||||
txn.call_after(self.store.get_relations_for_event.invalidate, (parent_id,))
|
||||
txn.call_after(
|
||||
self.store.get_aggregation_groups_for_event.invalidate, (parent_id,)
|
||||
self.store.get_relations_for_event.invalidate, (relation.parent_id,)
|
||||
)
|
||||
txn.call_after(
|
||||
self.store.get_aggregation_groups_for_event.invalidate,
|
||||
(relation.parent_id,),
|
||||
)
|
||||
|
||||
if rel_type == RelationTypes.REPLACE:
|
||||
txn.call_after(self.store.get_applicable_edit.invalidate, (parent_id,))
|
||||
if relation.rel_type == RelationTypes.REPLACE:
|
||||
txn.call_after(
|
||||
self.store.get_applicable_edit.invalidate, (relation.parent_id,)
|
||||
)
|
||||
|
||||
if rel_type == RelationTypes.THREAD:
|
||||
txn.call_after(self.store.get_thread_summary.invalidate, (parent_id,))
|
||||
if relation.rel_type == RelationTypes.THREAD:
|
||||
txn.call_after(
|
||||
self.store.get_thread_summary.invalidate, (relation.parent_id,)
|
||||
)
|
||||
# It should be safe to only invalidate the cache if the user has not
|
||||
# previously participated in the thread, but that's difficult (and
|
||||
# potentially error-prone) so it is always invalidated.
|
||||
txn.call_after(
|
||||
self.store.get_thread_participated.invalidate,
|
||||
(parent_id, event.sender),
|
||||
(relation.parent_id, event.sender),
|
||||
)
|
||||
|
||||
def _handle_insertion_event(
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue