Beispiel #1
0
 def _min_max_uuid_from_args(self, from_dt, to_dt, before, after):
     if after is not None or before is not None:
         min_uuid = after or util.MIN_UUID
         max_uuid = before or util.MAX_UUID
     else:
         min_uuid = util.uuid_for_prev_dt(util.uuid_with_dt(from_dt)) \
             if from_dt is not None else util.MIN_UUID
         max_uuid = util.uuid_for_next_dt(util.uuid_with_dt(to_dt)) \
             if to_dt is not None else util.MAX_UUID
     return min_uuid, max_uuid
Beispiel #2
0
def get_series_values(series_def,
                      report,
                      from_dt,
                      to_dt,
                      limit=mqeconfig.MAX_SERIES_POINTS_IN_TILE,
                      latest_instance_id=None):
    """Retrieves a list of :class:`SeriesValue` objects for a given time range.
    The function inserts new data series values if they haven't been already created
    for the requested time period.

    :param SeriesDef series_def: a series definition for which to get data
    :param ~mqe.report.Report report: a report for which to get data
    :param ~datetime.datetime from_dt: starting datetime
    :param ~datetime.datetime to_dt: ending datetime
    :param int limit: the limit of the series values to fetch/create
    :param latest_instance_id: (optional) a latest report instance ID of the report and tags
        (if not passed, the value will be fetched)
    :return: a list of :class:`SeriesValue` objects in the order of creation time of the corresponding report instances
    """
    assert from_dt is not None and to_dt is not None
    if series_def.from_dt is None or series_def.to_dt is None:
        insert_series_values(series_def, report, from_dt, to_dt, limit=limit)
    else:
        if from_dt < series_def.from_dt:
            insert_series_values(series_def,
                                 report,
                                 from_dt,
                                 prev_dt(series_def.from_dt),
                                 limit=limit)

        if not latest_instance_id:
            latest_instance_id = report.fetch_latest_instance_id(
                series_def.tags)
        if latest_instance_id is not None \
                and util.uuid_lt(series_def['to_rid'], latest_instance_id) \
                and to_dt >= series_def.to_dt:
            insert_series_values(series_def,
                                 report,
                                 None,
                                 None,
                                 after=series_def['to_rid'],
                                 limit=limit)

    min_report_instance_id = util.uuid_for_prev_dt(util.uuid_with_dt(from_dt))
    max_report_instance_id = util.uuid_for_next_dt(util.uuid_with_dt(to_dt))
    rows = c.dao.SeriesValueDAO.select_multi(series_def.series_id,
                                             min_report_instance_id,
                                             max_report_instance_id, limit)

    log.debug('Selected %d series_values by dates series_id=%s report_name=%r',
              len(rows), series_def.series_id, report.report_name)
    return list(reversed([SeriesValue(row) for row in rows]))
Beispiel #3
0
    def fetch_instances(self,
                        from_dt=None,
                        to_dt=None,
                        before=None,
                        after=None,
                        tags=None,
                        columns=None,
                        order='asc',
                        limit=100):
        """Fetch a list of report instances. The time range can be specified as either
        datetimes (``from_dt``, ``to_dt``) or report instance IDs (``before``, ``after``).

        :param ~datetime.datetime|None from_dt: fetch report instances created on the datetime or
            later
        :param ~datetime.datetime|None to_dt: fetch report instances created on the datetime or
            earlier
        :param ~uuid.UUID|None before: fetch instances created before the given report instance ID
        :param ~uuid.UUID|None after: fetch instances created after the given report instance ID
        :param list tags: a list of tags the returned instances must have attached
        :param str order: ``asc`` (ascending) or ``desc`` (descending) order wrt. creation datetime
        :param str columns: a list of :class:`ReportInstance` attributes to select
        :param int limit: the limit of the number of report instances to fetch
            fetch
        :return: a list of :class:`ReportInstance` objects
        """
        if after is not None or before is not None:
            min_uuid = after or util.MIN_UUID
            max_uuid = before or util.MAX_UUID
        else:
            min_uuid = util.uuid_for_prev_dt(util.uuid_with_dt(from_dt)) \
                       if from_dt is not None else util.MIN_UUID
            max_uuid = util.uuid_for_next_dt(util.uuid_with_dt(to_dt)) \
                       if to_dt is not None else util.MAX_UUID

        rows = c.dao.ReportInstanceDAO.select_multi(
            report_id=self.report_id,
            tags=tags,
            min_report_instance_id=min_uuid,
            max_report_instance_id=max_uuid,
            columns=columns,
            order=order,
            limit=limit)
        return [ReportInstance(row) for row in rows]
Beispiel #4
0
    def process_input(self,
                      input_string,
                      tags=None,
                      created=None,
                      input_type='any',
                      ip_options={},
                      force_header=None,
                      extra_ri_data=None,
                      handle_tpcreator=True,
                      handle_sscreator=True):
        """Process an input string - parse it into a table and create a report instance belonging
        to the report.

        :param str|unicode input_string: the input string
        :param list tags: a list of string tags attached to the report instance
        :param ~datetime.datetime created: an explicit creation datetime of the report instance (
            default: the current datetime)
        :param str input_type: input type (see :func:`mqetables.parseany.parse_input`)
        :param dict ip_options: extra parser options (see :func:`mqetables.parsing.InputParser`)
        :param force_header: a list of header rows indexes to set as a header (defaults to
            auto-detection)
        :param extra_ri_data: a custom JSON-serializable document attached to the report instance
        :param handle_tpcreator: whether to handle TPCreator for the created report instance
            by calling :func:`~mqe.tpcreator.handle_tpcreator`
        :param handle_sscreator: whether to handle SSCS by calling :func:`~mqe.sscreator.handle_sscreator`
        :return: an :class:`InputProcessingResult`
        """
        assert isinstance(input_string, (str, unicode))

        # disallow 'created' in the future
        now = datetime.datetime.utcnow()
        if created is not None and created.tzinfo:
            created = util.make_tz_naive(created)

        if created is not None and created.year < 2000:
            raise ValueError('created cannot be before the year 2000')

        if created is not None and created < now:
            report_instance_id = util.uuid_with_dt(created)
            custom_created = True
        else:
            custom_created = False
            report_instance_id = gen_timeuuid()
            created = util.datetime_from_uuid1(report_instance_id)

        if tags is None:
            tags = []

        parsing_result = parseany.parse_input(input_string, input_type,
                                              ip_options)
        table = mqeconfig.get_table_from_parsing_result(parsing_result)
        if table is None:
            return InputProcessingResult(None, parsing_result)

        if force_header is not None:
            log.debug('Overwriting header detection due to force_header')
            table.header_idxs = [
                i for i in force_header if util.valid_index(table.num_rows, i)
            ]
            table.header_idxs_source = parsing.HEADER_IDXS_SOURCE_USER

        ri_data_dict = {
            'table': table,
        }
        result_desc = self._get_result_desc(parsing_result)
        if result_desc:
            ri_data_dict['result_desc'] = result_desc

        report_instance_row = c.dao.ReportInstanceDAO.insert(
            owner_id=self.owner_id,
            report_id=self.report_id,
            report_instance_id=report_instance_id,
            tags=tags,
            ri_data=serialize.mjson(ri_data_dict),
            input_string=parsing_result.input_string,
            extra_ri_data=serialize.mjson(extra_ri_data)
            if extra_ri_data else None,
            custom_created=custom_created)

        report_instance = ReportInstance(report_instance_row)

        log.info(
            'Created new report instance report_id=%s report_name=%r tags=%s '
            'report_instance_id=%s created=%s', self.report_id,
            self.report_name, tags, report_instance_id,
            report_instance.created)

        if tags and handle_tpcreator:
            from mqe import tpcreator
            tpcreator.handle_tpcreator(self.owner_id, self.report_id,
                                       report_instance)

        if handle_sscreator:
            from mqe import sscreator
            sscreator.handle_sscreator(self.owner_id, self.report_id,
                                       report_instance)

        if custom_created:
            from mqe import dataseries
            dataseries.clear_series_defs(self.report_id, util.powerset(tags))

        return InputProcessingResult(report_instance, parsing_result)