Reads hunt log entries of a given hunt using given query options.

def ReadHuntLogEntries(self,
                         hunt_id,
                         offset,
                         count,
                         with_substring=None,
                         cursor=None):
    """Reads hunt log entries of a given hunt using given query options."""
    hunt_id_int = db_utils.HuntIDToInt(hunt_id)

    query = ("SELECT client_id, flow_id, message, UNIX_TIMESTAMP(timestamp) "
             "FROM flow_log_entries "
             "FORCE INDEX(flow_log_entries_by_hunt) "
             "WHERE hunt_id = %s AND flow_id = hunt_id ")

    args = [hunt_id_int]

    if with_substring is not None:
      query += "AND message LIKE %s "
      args.append("%" + db_utils.EscapeWildcards(with_substring) + "%")

    query += "ORDER BY timestamp ASC LIMIT %s OFFSET %s"

    args.append(count)
    args.append(offset)

    cursor.execute(query, args)

    flow_log_entries = []
    for client_id_int, flow_id_int, message, timestamp in cursor.fetchall():
      flow_log_entries.append(
          rdf_flow_objects.FlowLogEntry(
              client_id=db_utils.IntToClientID(client_id_int),
              flow_id=db_utils.IntToFlowID(flow_id_int),
              hunt_id=hunt_id,
              message=message,
              timestamp=mysql_utils.TimestampToRDFDatetime(timestamp)))

    return flow_log_entries