def make_query(self, query):
        """ optimize the query for supported index names """

        try:
            zc = aq_parent(aq_parent(self))
            skip = zc.getProperty('skip_compositeindex', False)
            if skip:
                LOG.debug('%(context)s: skip composite query build '
                          'for %(zcatalog)r', dict(
                              context=self.__class__.__name__,
                              zcatalog=zc))
                return query
        except AttributeError:
            pass

        if len(self) == 0:
            return query

        cquery = query.copy()
        components = self.getIndexComponents()

        # collect components matching query attributes
        # and check them for completeness
        c_records = []

        # component ids containing 'not' operator
        not_cids = []

        for c in components:
            query_options = QUERY_OPTIONS[c.meta_type]
            query_operators = QUERY_OPERATORS[c.meta_type]
            rec = IndexQuery(query, c.id, query_options,
                             query_operators[0], query_operators[1])
            opr = None

            # not supported: 'range' parameter
            range_parm = rec.get('range', None)
            if range_parm:
                opr = 'range'
            if rec.get('usage', None):
                # see if any usage params are sent to field
                opr = rec.usage.lower().split(':')
            if opr == 'range':
                continue

            # not supported: 'and' operator
            if rec.keys and rec.operator == 'and':
                continue

            # continue if no keys in query were set
            if rec.keys is None:
                continue

            # convert rec keys to int for BooleanIndex
            if c.meta_type == 'BooleanIndex':
                rec.keys = [int(bool(v)) for v in rec.keys[:]]

            # rec with 'not' parameter
            not_parm = rec.get('not', None)
            if not_parm:
                # not supported: 'pure not'
                if len(rec.keys) == 0:
                    continue
                not_cids.append(c.id)
                if c.meta_type == 'BooleanIndex':
                    not_parm = [int(bool(v)) for v in not_parm[:]]
                    rec.set('not', not_parm)

            c_records.append((c.id, rec))

        # return if less than MIN_COMPONENTS query attributes were caught
        if len(c_records) < MIN_COMPONENTS:
            return query

        records = ()
        kw_list = collect(c_records)
        # permute keyword list
        records = tuple(product(*kw_list))

        not_records = set()
        for c_id in not_cids:
            kw_list = collect(c_records, not_cid=c_id)
            if kw_list:
                not_records.update(product(*kw_list))
        # permute keyword list for 'not' operator
        not_records = tuple(not_records)

        # substitute matching query attributes as composite index
        if records and not_records:
            cquery.update({self.id: {'query': records, 'not': not_records}})
        elif records:
            cquery.update({self.id: {'query': records}})
        elif not_records:
            cquery.update({self.id: {'not': not_records}})

        # delete original matching query attributes from query
        for c_id, rec in c_records:
            if c_id in cquery:
                del cquery[c_id]

        return cquery
Example #2
0
    def make_query(self, query):
        """ optimize the query for supported index names """

        try:
            zc = aq_parent(aq_parent(self))
            skip = zc.getProperty('skip_compositeindex', False)
            if skip:
                LOG.debug(
                    '%(context)s: skip composite query build '
                    'for %(zcatalog)r',
                    dict(context=self.__class__.__name__, zcatalog=zc))
                return query
        except AttributeError:
            pass

        if len(self) == 0:
            return query

        cquery = query.copy()
        components = self.getIndexComponents()

        # collect components matching query attributes
        # and check them for completeness
        c_records = []
        for c in components:
            query_options = QUERY_OPTIONS[c.meta_type]
            query_operators = QUERY_OPERATORS[c.meta_type]
            rec = IndexQuery(query, c.id, query_options, query_operators[0],
                             query_operators[1])

            # not supported: 'not' parameter
            not_parm = rec.get('not', None)
            if not rec.keys and not_parm:
                continue

            # not supported: 'and' operator
            if rec.keys and rec.operator == 'and':
                continue

            # continue if no keys in query were set
            if rec.keys is None:
                continue

            # convert rec keys to int for BooleanIndex
            if c.meta_type == 'BooleanIndex':
                rec.keys = [int(bool(v)) for v in rec.keys[:]]

            c_records.append((c.id, rec))

        # return if less than MIN_COMPONENTS query attributes were caught
        if len(c_records) < MIN_COMPONENTS:
            return query

        kw_list = []
        for c_id, rec in c_records:
            kw = rec.keys
            if not kw:
                continue
            if isinstance(kw, list):
                kw = tuple(kw)
            elif not isinstance(kw, tuple):
                kw = (kw, )
            kw = tuple([(c_id, k) for k in kw])
            kw_list.append(kw)

        # permute keyword list
        records = tuple(product(*kw_list))

        # substitute matching query attributes as composite index
        cquery.update({self.id: {'query': records}})

        # delete original matching query attributes from query
        for c_id, rec in c_records:
            if c_id in cquery:
                del cquery[c_id]

        return cquery
    def make_query(self, query):
        """ optimize the query for supported index names """

        try:
            zc = aq_parent(aq_parent(self))
            skip = zc.getProperty('skip_compositeindex', False)
            if skip:
                LOG.debug(
                    '%(context)s: skip composite query build '
                    'for %(zcatalog)r',
                    dict(context=self.__class__.__name__, zcatalog=zc))
                return query
        except AttributeError:
            pass

        if len(self) == 0:
            return query

        cquery = query.copy()
        components = self.getIndexComponents()

        # collect components matching query attributes
        # and check them for completeness
        c_records = []

        # component ids containing 'not' operator
        not_cids = []

        for c in components:
            query_options = QUERY_OPTIONS[c.meta_type]
            query_operators = QUERY_OPERATORS[c.meta_type]
            rec = IndexQuery(query, c.id, query_options, query_operators[0],
                             query_operators[1])
            opr = None

            # not supported: 'range' parameter
            range_parm = rec.get('range', None)
            if range_parm:
                opr = 'range'
            if rec.get('usage', None):
                # see if any usage params are sent to field
                opr = rec.usage.lower().split(':')
            if opr == 'range':
                continue

            # not supported: 'and' operator
            if rec.keys and rec.operator == 'and':
                continue

            # continue if no keys in query were set
            if rec.keys is None:
                continue

            # convert rec keys to int for BooleanIndex
            if c.meta_type == 'BooleanIndex':
                rec.keys = [int(bool(v)) for v in rec.keys[:]]

            # rec with 'not' parameter
            not_parm = rec.get('not', None)
            if not_parm:
                # not supported: 'pure not'
                if len(rec.keys) == 0:
                    continue
                not_cids.append(c.id)
                if c.meta_type == 'BooleanIndex':
                    not_parm = [int(bool(v)) for v in not_parm[:]]
                    rec.set('not', not_parm)

            c_records.append((c.id, rec))

        # return if less than MIN_COMPONENTS query attributes were caught
        if len(c_records) < MIN_COMPONENTS:
            return query

        records = ()
        kw_list = collect(c_records)
        # permute keyword list
        records = tuple(product(*kw_list))

        not_records = set()
        for c_id in not_cids:
            kw_list = collect(c_records, not_cid=c_id)
            if kw_list:
                not_records.update(product(*kw_list))
        # permute keyword list for 'not' operator
        not_records = tuple(not_records)

        # substitute matching query attributes as composite index
        if records and not_records:
            cquery.update({self.id: {'query': records, 'not': not_records}})
        elif records:
            cquery.update({self.id: {'query': records}})
        elif not_records:
            cquery.update({self.id: {'not': not_records}})

        # delete original matching query attributes from query
        for c_id, rec in c_records:
            if c_id in cquery:
                del cquery[c_id]

        return cquery