diff --git a/synapse/storage/__init__.py b/synapse/storage/__init__.py
index 3ad6f3a4d6..7a441391f0 100644
--- a/synapse/storage/__init__.py
+++ b/synapse/storage/__init__.py
@@ -19,6 +19,10 @@ from synapse.api.events.room import (
RoomMemberEvent, RoomTopicEvent, FeedbackEvent,
# RoomConfigEvent,
RoomNameEvent,
+ RoomJoinRulesEvent,
+ RoomPowerLevelsEvent,
+ RoomAddStateLevelEvent,
+ RoomSendEventLevelEvent,
)
from synapse.util.logutils import log_function
@@ -123,13 +127,19 @@ class DataStore(RoomMemberStore, RoomStore,
if event.type == RoomMemberEvent.TYPE:
self._store_room_member_txn(txn, event)
elif event.type == FeedbackEvent.TYPE:
- self._store_feedback_txn(txn,event)
-# elif event.type == RoomConfigEvent.TYPE:
-# self._store_room_config_txn(txn, event)
+ self._store_feedback_txn(txn, event)
elif event.type == RoomNameEvent.TYPE:
self._store_room_name_txn(txn, event)
elif event.type == RoomTopicEvent.TYPE:
self._store_room_topic_txn(txn, event)
+ elif event.type == RoomJoinRulesEvent.TYPE:
+ self._store_join_rule(txn, event)
+ elif event.type == RoomPowerLevelsEvent.TYPE:
+ self._store_power_levels(txn, event)
+ elif event.type == RoomAddStateLevelEvent.TYPE:
+ self._store_add_state_level(txn, event)
+ elif event.type == RoomSendEventLevelEvent.TYPE:
+ self._store_send_event_level(txn, event)
vals = {
"topological_ordering": event.depth,
@@ -223,7 +233,6 @@ class DataStore(RoomMemberStore, RoomStore,
defer.returnValue(self.min_token)
-
def snapshot_room(self, room_id, user_id, state_type=None, state_key=None):
"""Snapshot the room for an update by a user
Args:
diff --git a/synapse/storage/room.py b/synapse/storage/room.py
index d1f1a232f8..3ca07f4350 100644
--- a/synapse/storage/room.py
+++ b/synapse/storage/room.py
@@ -27,6 +27,9 @@ import logging
logger = logging.getLogger(__name__)
+OpsLevel = collections.namedtuple("OpsLevel", ("ban_level", "kick_level"))
+
+
class RoomStore(SQLBaseStore):
@defer.inlineCallbacks
@@ -129,6 +132,98 @@ class RoomStore(SQLBaseStore):
defer.returnValue(ret)
+ @defer.inlineCallbacks
+ def get_room_join_rule(self, room_id):
+ sql = (
+ "SELECT join_rule FROM room_join_rules as r "
+ "INNER JOIN current_state_events as c "
+ "ON r.event_id = c.event_id "
+ "WHERE c.room_id = ? "
+ )
+
+ rows = yield self._execute(None, sql, room_id)
+
+ if len(rows) == 1:
+ defer.returnValue(rows[0][0])
+ else:
+ defer.returnValue(None)
+
+ def get_power_level(self, room_id, user_id):
+ return self._db_pool.runInteraction(
+ self._get_power_level,
+ room_id, user_id,
+ )
+
+ def _get_power_level(self, txn, room_id, user_id):
+ sql = (
+ "SELECT level FROM room_power_levels as r "
+ "INNER JOIN current_state_events as c "
+ "ON r.event_id = c.event_id "
+ "WHERE c.room_id = ? AND r.user_id = ? "
+ )
+
+ rows = txn.execute(sql, (room_id, user_id,)).fetchall()
+
+ if len(rows) == 1:
+ return rows[0][0]
+
+ sql = (
+ "SELECT level FROM room_default_levels as r "
+ "INNER JOIN current_state_events as c "
+ "ON r.event_id = c.event_id "
+ "WHERE c.room_id = ? "
+ )
+
+ rows = txn.execute(sql, (room_id,)).fetchall()
+
+ if len(rows) == 1:
+ return rows[0][0]
+ else:
+ return None
+
+ def get_ops_levels(self, room_id):
+ return self._db_pool.runInteraction(
+ self._get_ops_levels,
+ room_id,
+ )
+
+ def _get_ops_levels(self, txn, room_id):
+ sql = (
+ "SELECT ban_level, kick_level FROM room_ops_levels as r "
+ "INNER JOIN current_state_events as c "
+ "ON r.event_id = c.event_id "
+ "WHERE c.room_id = ? "
+ )
+
+ rows = txn.execute(sql, (room_id,)).fetchall()
+
+ if len(rows) == 1:
+ return OpsLevel(rows[0][0], rows[0][1])
+ else:
+ return OpsLevel(None, None)
+
+ def get_add_state_level(self, room_id):
+ return self._get_level_from_table("room_add_state_levels", room_id)
+
+ def get_send_event_level(self, room_id):
+ return self._get_level_from_table("room_send_event_levels", room_id)
+
+ @defer.inlineCallbacks
+ def _get_level_from_table(self, table, room_id):
+ sql = (
+ "SELECT level FROM %(table)s as r "
+ "INNER JOIN current_state_events as c "
+ "ON r.event_id = c.event_id "
+ "WHERE c.room_id = ? "
+ ) % {"table": table}
+
+ rows = yield self._execute(None, sql, room_id)
+
+ if len(rows) == 1:
+ defer.returnValue(rows[0][0])
+ else:
+ defer.returnValue(None)
+
def _store_room_topic_txn(self, txn, event):
self._simple_insert_txn(
txn,
@@ -151,6 +246,92 @@ class RoomStore(SQLBaseStore):
}
)
+ def _store_join_rule(self, txn, event):
+ self._simple_insert_txn(
+ txn,
+ "room_join_rules",
+ {
+ "event_id": event.event_id,
+ "room_id": event.room_id,
+ "join_rule": event.content["join_rule"],
+ },
+ )
+
+ def _store_power_levels(self, txn, event):
+ for user_id, level in event.content.items():
+ if user_id == "default":
+ self._simple_insert_txn(
+ txn,
+ "room_default_levels",
+ {
+ "event_id": event.event_id,
+ "room_id": event.room_id,
+ "level": level,
+ },
+ )
+ else:
+ self._simple_insert_txn(
+ txn,
+ "room_power_levels",
+ {
+ "event_id": event.event_id,
+ "room_id": event.room_id,
+ "user_id": user_id,
+ "level": level
+ },
+ )
+
+ def _store_default_level(self, txn, event):
+ self._simple_insert_txn(
+ txn,
+ "room_default_levels",
+ {
+ "event_id": event.event_id,
+ "room_id": event.room_id,
+ "level": event.content["default_level"],
+ },
+ )
+
+ def _store_add_state_level(self, txn, event):
+ self._simple_insert_txn(
+ txn,
+ "room_add_state_levels",
+ {
+ "event_id": event.event_id,
+ "room_id": event.room_id,
+ "level": event.content["level"],
+ },
+ )
+
+ def _store_send_event_level(self, txn, event):
+ self._simple_insert_txn(
+ txn,
+ "room_send_event_levels",
+ {
+ "event_id": event.event_id,
+ "room_id": event.room_id,
+ "level": event.content["level"],
+ },
+ )
+
+ def _store_ops_level(self, txn, event):
+ content = {
+ "event_id": event.event_id,
+ "room_id": event.room_id,
+ }
+
+ if "kick_level" in event.content:
+ content["kick_level"] = event.content["kick_level"]
+
+ if "ban_level" in event.content:
+ content["ban_level"] = event.content["ban_level"]
+
+ self._simple_insert_txn(
+ txn,
+ "room_send_event_levels",
+ content,
+ )
+
class RoomsTable(Table):
table_name = "rooms"
diff --git a/synapse/storage/schema/im.sql b/synapse/storage/schema/im.sql
index e92f21ef3b..dbefbbda31 100644
--- a/synapse/storage/schema/im.sql
+++ b/synapse/storage/schema/im.sql
@@ -96,8 +96,71 @@ CREATE TABLE IF NOT EXISTS rooms(
creator TEXT
);
+CREATE TABLE IF NOT EXISTS room_join_rules(
+ event_id TEXT NOT NULL,
+ room_id TEXT NOT NULL,
+ join_rule TEXT NOT NULL
+);
+CREATE INDEX IF NOT EXISTS room_join_rules_event_id ON room_join_rules(event_id);
+CREATE INDEX IF NOT EXISTS room_join_rules_room_id ON room_join_rules(room_id);
+
+
+CREATE TABLE IF NOT EXISTS room_power_levels(
+ event_id TEXT NOT NULL,
+ room_id TEXT NOT NULL,
+ user_id TEXT NOT NULL,
+ level INTEGER NOT NULL
+);
+CREATE INDEX IF NOT EXISTS room_power_levels_event_id ON room_power_levels(event_id);
+CREATE INDEX IF NOT EXISTS room_power_levels_room_id ON room_power_levels(room_id);
+CREATE INDEX IF NOT EXISTS room_power_levels_room_user ON room_power_levels(room_id, user_id);
+
+
+CREATE TABLE IF NOT EXISTS room_default_levels(
+ event_id TEXT NOT NULL,
+ room_id TEXT NOT NULL,
+ level INTEGER NOT NULL
+);
+
+CREATE INDEX IF NOT EXISTS room_default_levels_event_id ON room_default_levels(event_id);
+CREATE INDEX IF NOT EXISTS room_default_levels_room_id ON room_default_levels(room_id);
+
+
+CREATE TABLE IF NOT EXISTS room_add_state_levels(
+ event_id TEXT NOT NULL,
+ room_id TEXT NOT NULL,
+ level INTEGER NOT NULL
+);
+
+CREATE INDEX IF NOT EXISTS room_add_state_levels_event_id ON room_add_state_levels(event_id);
+CREATE INDEX IF NOT EXISTS room_add_state_levels_room_id ON room_add_state_levels(room_id);
+
+
+CREATE TABLE IF NOT EXISTS room_send_event_levels(
+ event_id TEXT NOT NULL,
+ room_id TEXT NOT NULL,
+ level INTEGER NOT NULL
+);
+
+CREATE INDEX IF NOT EXISTS room_send_event_levels_event_id ON room_send_event_levels(event_id);
+CREATE INDEX IF NOT EXISTS room_send_event_levels_room_id ON room_send_event_levels(room_id);
+
+
+CREATE TABLE IF NOT EXISTS room_ops_levels(
+ event_id TEXT NOT NULL,
+ room_id TEXT NOT NULL,
+ ban_level INTEGER,
+ kick_level INTEGER
+);
+
+CREATE INDEX IF NOT EXISTS room_ops_levels_event_id ON room_ops_levels(event_id);
+CREATE INDEX IF NOT EXISTS room_ops_levels_room_id ON room_ops_levels(room_id);
+
+
CREATE TABLE IF NOT EXISTS room_hosts(
room_id TEXT NOT NULL,
host TEXT NOT NULL,
CONSTRAINT room_hosts_uniq UNIQUE (room_id, host) ON CONFLICT IGNORE
);
+
+CREATE INDEX IF NOT EXISTS room_hosts_room_id ON room_hosts (room_id);
|