diff --git a/synapse/api/events/__init__.py b/synapse/api/events/__init__.py
index f95468fc65..5f300de108 100644
--- a/synapse/api/events/__init__.py
+++ b/synapse/api/events/__init__.py
@@ -157,7 +157,12 @@ class SynapseEvent(JsonEncodedObject):
class SynapseStateEvent(SynapseEvent):
- def __init__(self, **kwargs):
+
+ valid_keys = SynapseEvent.valid_keys + [
+ "prev_content",
+ ]
+
+ def __init__(self, **kwargs):
if "state_key" not in kwargs:
kwargs["state_key"] = ""
super(SynapseStateEvent, self).__init__(**kwargs)
diff --git a/synapse/storage/__init__.py b/synapse/storage/__init__.py
index d97014f4da..81c3c94b2e 100644
--- a/synapse/storage/__init__.py
+++ b/synapse/storage/__init__.py
@@ -81,7 +81,7 @@ class DataStore(RoomMemberStore, RoomStore,
defer.returnValue(latest)
@defer.inlineCallbacks
- def get_event(self, event_id):
+ def get_event(self, event_id, allow_none=False):
events_dict = yield self._simple_select_one(
"events",
{"event_id": event_id},
@@ -92,8 +92,12 @@ class DataStore(RoomMemberStore, RoomStore,
"content",
"unrecognized_keys"
],
+ allow_none=allow_none,
)
+ if not events_dict:
+ defer.returnValue(None)
+
event = self._parse_event_from_row(events_dict)
defer.returnValue(event)
@@ -220,7 +224,8 @@ class DataStore(RoomMemberStore, RoomStore,
results = yield self._execute_and_decode(sql, *args)
- defer.returnValue([self._parse_event_from_row(r) for r in results])
+ events = yield self._parse_events(results)
+ defer.returnValue(events)
@defer.inlineCallbacks
def _get_min_token(self):
diff --git a/synapse/storage/_base.py b/synapse/storage/_base.py
index bae50e7d1f..8037225079 100644
--- a/synapse/storage/_base.py
+++ b/synapse/storage/_base.py
@@ -312,6 +312,25 @@ class SQLBaseStore(object):
**d
)
+ def _parse_events(self, rows):
+ return self._db_pool.runInteraction(self._parse_events_txn, rows)
+
+ def _parse_events_txn(self, txn, rows):
+ events = [self._parse_event_from_row(r) for r in rows]
+
+ sql = "SELECT * FROM events WHERE event_id = ?"
+
+ for ev in events:
+ if hasattr(ev, "prev_state"):
+ # Load previous state_content.
+ # TODO: Should we be pulling this out above?
+ cursor = txn.execute(sql, (ev.prev_state,))
+ prevs = self.cursor_to_dict(cursor)
+ if prevs:
+ prev = self._parse_event_from_row(prevs[0])
+ ev.prev_content = prev.content
+
+ return events
class Table(object):
""" A base class used to store information about a particular table.
diff --git a/synapse/storage/roommember.py b/synapse/storage/roommember.py
index 75c9a60101..9a393e2568 100644
--- a/synapse/storage/roommember.py
+++ b/synapse/storage/roommember.py
@@ -88,7 +88,7 @@ class RoomMemberStore(SQLBaseStore):
txn.execute(sql, (user_id, room_id))
rows = self.cursor_to_dict(txn)
if rows:
- return self._parse_event_from_row(rows[0])
+ return self._parse_events_txn(txn, rows)[0]
else:
return None
@@ -161,7 +161,7 @@ class RoomMemberStore(SQLBaseStore):
# logger.debug("_get_members_query Got rows %s", rows)
- results = [self._parse_event_from_row(r) for r in rows]
+ results = yield self._parse_events(rows)
defer.returnValue(results)
@defer.inlineCallbacks
diff --git a/synapse/storage/stream.py b/synapse/storage/stream.py
index 2cb0067a67..aff6dc9855 100644
--- a/synapse/storage/stream.py
+++ b/synapse/storage/stream.py
@@ -188,7 +188,7 @@ class StreamStore(SQLBaseStore):
user_id, user_id, from_id, to_id
)
- ret = [self._parse_event_from_row(r) for r in rows]
+ ret = yield self._parse_events(rows)
if rows:
key = "s%d" % max([r["stream_ordering"] for r in rows])
@@ -243,9 +243,11 @@ class StreamStore(SQLBaseStore):
# TODO (erikj): We should work out what to do here instead.
next_token = to_key if to_key else from_key
+ events = yield self._parse_events(rows)
+
defer.returnValue(
(
- [self._parse_event_from_row(r) for r in rows],
+ events,
next_token
)
)
@@ -277,12 +279,11 @@ class StreamStore(SQLBaseStore):
else:
token = (end_token, end_token)
- defer.returnValue(
- (
- [self._parse_event_from_row(r) for r in rows],
- token
- )
- )
+ events = yield self._parse_events(rows)
+
+ ret = (events, token)
+
+ defer.returnValue(ret)
def get_room_events_max_id(self):
return self._db_pool.runInteraction(self._get_room_events_max_id_txn)
|