'Get a list of the most recent unread push actions for a given user,
within the given stream ordering range. Called by the httppusher.
Args:
user_id (str): The user to fetch push actions for.
min_stream_ordering(int): The exclusive lower bound on the
stream ordering of event push actions to fetch.
max_stream_ordering(int): The inclusive upper bound on the
stream ordering of event push actions to fetch.
limit (int): The maximum number of rows to return.
Returns:
A promise which resolves to a list of dicts with the keys "event_id",
"room_id", "stream_ordering", "actions".
The list will be ordered by ascending stream_ordering.
The list will have between 0~limit entries.'

@defer.inlineCallbacks
def get_unread_push_actions_for_user_in_range_for_http(self, user_id, min_stream_ordering, max_stream_ordering, limit=20):

    def get_after_receipt(txn):
        sql = "SELECT    ep.event_id,    ep.room_id,    ep.stream_ordering,    ep.actions,            ep.highlight        FROM    (            SELECT    room_id,                            MAX(topological_ordering)    as    topological_ordering,                            MAX(stream_ordering)    as    stream_ordering            FROM    events            INNER    JOIN    receipts_linearized    USING    (room_id,    event_id)            WHERE    receipt_type    =    'm.read'    AND    user_id    =    ?            GROUP    BY    room_id)    AS    rl,    event_push_actions    AS    ep    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    >    rl.stream_ordering                            )            )            AND    ep.user_id    =    ?            AND    ep.stream_ordering    >    ?            AND    ep.stream_ordering    <=    ?    ORDER    BY    ep.stream_ordering    ASC    LIMIT    ?"
        args = [user_id, user_id, min_stream_ordering, max_stream_ordering, limit]
        txn.execute(sql, args)
        return txn.fetchall()
    after_read_receipt = (yield self.runInteraction('get_unread_push_actions_for_user_in_range_http_arr', get_after_receipt))
    def get_no_receipt(txn):
        sql = "SELECT    ep.event_id,    ep.room_id,    ep.stream_ordering,    ep.actions,            ep.highlight        FROM    event_push_actions    AS    ep    INNER    JOIN    events    AS    e    USING    (room_id,    event_id)    WHERE            ep.room_id    NOT    IN    (                    SELECT    room_id    FROM    receipts_linearized                            WHERE    receipt_type    =    'm.read'    AND    user_id    =    ?                            GROUP    BY    room_id            )            AND    ep.user_id    =    ?            AND    ep.stream_ordering    >    ?            AND    ep.stream_ordering    <=    ?    ORDER    BY    ep.stream_ordering    ASC    LIMIT    ?"
        args = [user_id, user_id, min_stream_ordering, max_stream_ordering, limit]
        txn.execute(sql, args)
        return txn.fetchall()
    no_read_receipt = (yield self.runInteraction('get_unread_push_actions_for_user_in_range_http_nrr', get_no_receipt))
    notifs = [{'event_id': row[0], 'room_id': row[1], 'stream_ordering': row[2], 'actions': _deserialize_action(row[3], row[4])} for row in (after_read_receipt + no_read_receipt)]
    notifs.sort(key=(lambda r: r['stream_ordering']))
    defer.returnValue(notifs[:limit])
