@defer.inlineCallbacks
    def get_all_updated_tags(self, last_id, current_id, limit):
        def get_all_updated_tags_txn(txn):
            sql = (
                "SELECT stream_id, user_id, room_id"
                " FROM room_tags_revisions as r"
                " WHERE ? < stream_id AND stream_id <= ?"
                " ORDER BY stream_id ASC LIMIT ?"
            )
            txn.execute(sql, (last_id, current_id, limit))
            return txn.fetchall()

        tag_ids = yield self.runInteraction(
            "get_all_updated_tags", get_all_updated_tags_txn
        )

        def get_tag_content(txn, tag_ids):
            sql = (
                "SELECT tag, content"
                " FROM room_tags"
                " WHERE user_id=? AND room_id=?"
            )
            results = []
            for stream_id, user_id, room_id in tag_ids:
                txn.execute(sql, (user_id, room_id))
                tags = []
                for tag, content in txn.fetchall():
                    tags.append(json.dumps(tag) + ":" + content)
                tag_json = "{" + ",".join(tags) + "}"
                results.append((stream_id, user_id, room_id, tag_json))

            return results

        batch_size = 50
        results = []
        for i in xrange(0, len(tag_ids), batch_size):
            tags = yield self.runInteraction(
                "get_all_updated_tag_content",
                get_tag_content,
                tag_ids[i:i + batch_size],
            )
            results.extend(tags)

        defer.returnValue(results)
Get all the client tags that have changed on the server
dataset/ETHPy150Open matrix-org/synapse/synapse/storage/tags.py/TagsStore.get_all_updated_tags