Exemplo n.º 1
0
    def delete(self, owner_id, report_id, report_instance_id):
        ri = self.select(report_id, report_instance_id, None)
        if not ri:
            return False

        diskspace = self._compute_ri_diskspace(ri)
        tags_powerset = util.powerset(ri['all_tags'])

        with cursor() as cur:
            cur.execute(
                """DELETE FROM report_instance WHERE report_id=?
                           AND tags IN {in_p} AND report_instance_id=?""".
                format(in_p=in_params(tags_powerset)),
                [report_id] + tags_powerset + [report_instance_id])

            # report counts

            cur.execute(
                """UPDATE report SET
                           report_instance_count = report_instance_count - 1
                           WHERE report_id=?""", [report_id])
            cur.execute(
                """UPDATE report SET
                           report_instance_diskspace = report_instance_diskspace - ?
                           WHERE report_id=?""", [diskspace, report_id])

            # owner counts

            cur.execute(
                """UPDATE report_data_for_owner
                           SET report_instance_count=report_instance_count-1
                           WHERE owner_id=?""", [owner_id])
            cur.execute(
                """UPDATE report_data_for_owner
                           SET report_instance_diskspace=report_instance_diskspace-?
                           WHERE owner_id=?""", [diskspace, owner_id])

        return True
Exemplo n.º 2
0
    def _delete_ris(self, owner_id, report_id, tags, ris, update_counters):
        qs = []
        tags_days = set()
        all_tags_subsets = set()

        with cursor() as cur:
            for ri in ris:
                tags_powerset = util.powerset(ri['all_tags'])
                cur.execute("""DELETE FROM report_instance WHERE report_id=?
                               AND tags IN {in_p} AND report_instance_id=?""".format(in_p=in_params(tags_powerset)),
                            [report_id] + tags_powerset + [ri['report_instance_id']])
                day = util.datetime_from_uuid1(ri['report_instance_id']).date()
                for tags_subset in tags_powerset:
                    tags_days.add((tuple(tags_subset), day))
                    all_tags_subsets.add(tuple(tags_subset))

            if update_counters:
                total_diskspace = sum(self._compute_ri_diskspace(ri) for ri in ris)
                cur.execute("""UPDATE report
                               SET report_instance_count = report_instance_count - ?
                               WHERE report_id=?""",
                            [len(ris), report_id])
                cur.execute("""UPDATE report
                               SET report_instance_diskspace = report_instance_diskspace - ?
                               WHERE report_id=?""",
                            [total_diskspace, report_id])
                cur.execute("""UPDATE report_data_for_owner
                               SET report_instance_count=report_instance_count - ?
                               WHERE owner_id=?""",
                            [len(ris), owner_id])
                cur.execute("""UPDATE report_data_for_owner
                               SET report_instance_diskspace=report_instance_diskspace - ?
                               WHERE owner_id=?""",
                            [total_diskspace, owner_id])


            ### Delete days for which report instances no longer exist

            for day_tags, day in tags_days:
                cur.execute("""SELECT report_instance_id FROM report_instance
                               WHERE report_id=? AND tags=? AND 
                               report_instance_id > ? AND report_instance_id < ?
                               LIMIT 1""",
                            [report_id, list(day_tags),
                             util.min_uuid_with_dt(datetime.datetime.combine(day,
                                                            datetime.datetime.min.time())),
                             util.max_uuid_with_dt(datetime.datetime.combine(day,
                                                            datetime.datetime.max.time()))])
                if not cur.fetchall():
                    cur.execute("""DELETE FROM report_instance_day
                                   WHERE report_id=? AND tags=? AND day=?""",
                                [report_id, list(day_tags), day])


            ### Delete tags for which report instances no longer exist

            tags_present = set()
            for tags, _ in tags_days:
                for tag in tags:
                    tags_present.add(tag)

            for tag in tags_present:
                cur.execute("""SELECT report_id FROM report_instance_day
                               WHERE report_id=? AND tags=?
                               LIMIT 1""",
                            [report_id, [tag]])
                if cur.fetchall():
                    continue
                cur.execute("""DELETE FROM report_tag
                               WHERE report_id=? AND tag=?""",
                            [report_id, tag])


            return len(ris), [list(ts) for ts in all_tags_subsets]
Exemplo n.º 3
0
    def insert(self, owner_id, report_id, report_instance_id, tags, ri_data,
               input_string, extra_ri_data, custom_created):
        created = util.datetime_from_uuid1(report_instance_id)

        with cursor() as cur:
            first_row = None
            tags_powerset = util.powerset(tags[:mqeconfig.MAX_TAGS])
            for tags_subset in tags_powerset:
                row = dict(report_id=report_id,
                           tags=tags_subset,
                           report_instance_id=report_instance_id,
                           ri_data=ri_data,
                           input_string=input_string,
                           all_tags=tags,
                           extra_ri_data=extra_ri_data)
                if first_row is None:
                    first_row = row
                cur.execute(*insert('report_instance', row))

                cur.execute(
                    """INSERT OR IGNORE INTO report_instance_day (report_id, tags, day)
                               VALUES (?, ?, ?)""",
                    [report_id, tags_subset,
                     created.date()])

            if first_row:
                # report counts

                cur.execute(
                    """UPDATE report SET
                               report_instance_count = report_instance_count + 1
                               WHERE report_id=?""", [report_id])

                diskspace = self._compute_ri_diskspace(first_row)
                cur.execute(
                    """UPDATE report SET
                               report_instance_diskspace = report_instance_diskspace + ?
                               WHERE report_id=?""", [diskspace, report_id])

                # owner counts
                cur.execute(
                    """SELECT 1 FROM report_data_for_owner WHERE owner_id=?""",
                    [owner_id])
                if not cur.fetchone():
                    try:
                        cur.execute(
                            """INSERT INTO report_data_for_owner (owner_id)
                                       VALUES (?)""", [owner_id])
                    except sqlite3.IntegrityError:
                        pass

                cur.execute(
                    """UPDATE report_data_for_owner
                               SET report_instance_count=report_instance_count+1
                               WHERE owner_id=?""", [owner_id])

                cur.execute(
                    """UPDATE report_data_for_owner
                               SET report_instance_diskspace=report_instance_diskspace+?
                               WHERE owner_id=?""", [diskspace, owner_id])

                for tag in tags:
                    cur.execute(
                        """INSERT OR IGNORE INTO report_tag (report_id, tag)
                                   VALUES (?, ?)""", [report_id, tag])

            return first_row
Exemplo n.º 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)