Example #1
0
  def _ReadCurrentFlowInfo(self, responses, currently_available_requests,
                           next_request_by_flow, responses_expected_by_request,
                           current_responses_by_request, cursor):
    """Reads stored data for flows we want to modify."""
    flow_conditions = []
    flow_args = []
    req_conditions = []
    req_args = []
    for r in responses:
      flow_conditions.append("(client_id=%s AND flow_id=%s)")
      flow_args.append(mysql_utils.ClientIDToInt(r.client_id))
      flow_args.append(mysql_utils.FlowIDToInt(r.flow_id))

      req_conditions.append("(client_id=%s AND flow_id=%s AND request_id=%s)")
      req_args.append(mysql_utils.ClientIDToInt(r.client_id))
      req_args.append(mysql_utils.FlowIDToInt(r.flow_id))
      req_args.append(r.request_id)

    flow_query = ("SELECT client_id, flow_id, next_request_to_process "
                  "FROM flows WHERE ")
    flow_query += " OR ".join(flow_conditions)

    req_query = ("SELECT client_id, flow_id, request_id, responses_expected "
                 "FROM flow_requests WHERE ")
    req_query += " OR ".join(req_conditions)

    res_query = ("SELECT client_id, flow_id, request_id, response_id "
                 "FROM flow_responses WHERE ")
    res_query += " OR ".join(req_conditions)

    cursor.execute(flow_query, flow_args)

    for row in cursor.fetchall():
      client_id_int, flow_id_int, next_request_to_process = row
      client_id = mysql_utils.IntToClientID(client_id_int)
      flow_id = mysql_utils.IntToFlowID(flow_id_int)
      next_request_by_flow[(client_id, flow_id)] = next_request_to_process

    cursor.execute(req_query, req_args)

    for row in cursor.fetchall():
      client_id_int, flow_id_int, request_id, responses_expected = row
      client_id = mysql_utils.IntToClientID(client_id_int)
      flow_id = mysql_utils.IntToFlowID(flow_id_int)
      request_key = (client_id, flow_id, request_id)
      currently_available_requests.add(request_key)
      if responses_expected:
        responses_expected_by_request[request_key] = responses_expected

    cursor.execute(res_query, req_args)

    for row in cursor.fetchall():
      client_id_int, flow_id_int, request_id, response_id = row
      client_id = mysql_utils.IntToClientID(client_id_int)
      flow_id = mysql_utils.IntToFlowID(flow_id_int)
      request_key = (client_id, flow_id, request_id)
      current_responses_by_request.setdefault(request_key,
                                              set()).add(response_id)
Example #2
0
    def WriteFlowRequests(self, requests, cursor=None):
        """Writes a list of flow requests to the database."""
        args = []
        templates = []
        flow_keys = []
        needs_processing = {}
        now_str = mysql_utils.RDFDatetimeToMysqlString(
            rdfvalue.RDFDatetime.Now())
        for r in requests:
            if r.needs_processing:
                needs_processing.setdefault((r.client_id, r.flow_id),
                                            []).append(r.request_id)

            flow_keys.append((r.client_id, r.flow_id))
            templates.append("(%s, %s, %s, %s, %s, %s)")
            args.extend([
                mysql_utils.ClientIDToInt(r.client_id),
                mysql_utils.FlowIDToInt(r.flow_id), r.request_id,
                r.needs_processing,
                r.SerializeToString(), now_str
            ])

        if needs_processing:
            flow_processing_requests = []
            nr_conditions = []
            nr_args = []
            for client_id, flow_id in needs_processing:
                nr_conditions.append("(client_id=%s AND flow_id=%s)")
                nr_args.append(mysql_utils.ClientIDToInt(client_id))
                nr_args.append(mysql_utils.FlowIDToInt(flow_id))

            nr_query = ("SELECT client_id, flow_id, next_request_to_process "
                        "FROM flows WHERE ")
            nr_query += " OR ".join(nr_conditions)

            cursor.execute(nr_query, nr_args)

            db_result = cursor.fetchall()
            for client_id_int, flow_id_int, next_request_to_process in db_result:
                client_id = mysql_utils.IntToClientID(client_id_int)
                flow_id = mysql_utils.IntToFlowID(flow_id_int)
                if next_request_to_process in needs_processing[(client_id,
                                                                flow_id)]:
                    flow_processing_requests.append(
                        rdf_flows.FlowProcessingRequest(client_id=client_id,
                                                        flow_id=flow_id))

            if flow_processing_requests:
                self._WriteFlowProcessingRequests(flow_processing_requests,
                                                  cursor)

        query = ("INSERT INTO flow_requests "
                 "(client_id, flow_id, request_id, needs_processing, request, "
                 "timestamp) VALUES ")
        query += ", ".join(templates)
        try:
            cursor.execute(query, args)
        except MySQLdb.IntegrityError as e:
            raise db.AtLeastOneUnknownFlowError(flow_keys, cause=e)