section_category=context.getGroup(base=1),
    strict_base_contribution_uid=base_contribution_uid_dict.values(),
    portal_type=portal_type,
    parent_portal_type=delivery_portal_type,
    simulation_state=('stopped', 'delivered'),
    mirror_date=dict(query=context.getStopDate(), range='ngt'),
    only_accountable=only_accountable,
)

if context.getValidationState() == 'validated':
    inventory_kw['default_aggregate_uid'] = context.getUid()
else:
    aggregate_base_category_uid = portal.portal_categories.aggregate.getUid()
    # TODO include context portal type
    inventory_kw['where_expression'] = SQLQuery(
        '(SELECT COUNT(uid) from category where '
        'base_category_uid=%s and uid=stock.uid) = 0' %
        aggregate_base_category_uid)

# get all resources that have been used with this inventory parameters
resource_list = [
    brain.resource_relative_url
    for brain in portal.portal_simulation.getInventoryList(group_by_node=0,
                                                           group_by_section=0,
                                                           group_by_resource=1,
                                                           **inventory_kw)
]

for resource_relative_url in resource_list:
    resource = portal.restrictedTraverse(resource_relative_url)
    inventory_kw['resource_uid'] = resource.getUid(),
Esempio n. 2
0
  def buildSQLQuery(self, strict_membership=0, table='category',
                          join_table='catalog', join_column='uid',
                          **kw):
    """
      A Predicate can be rendered as an SQL expression. This
      can be used to generate SQL requests in reports or in
      catalog search queries.

      XXX - This method is not implemented yet
    """
    # Build the identity criterion
    catalog_kw = {}
    catalog_kw.update(kw) # query_table, REQUEST, ignore_empty_string, **kw
    criterion_list = self.getCriterionList()
    # BBB: accessor is not present on old Predicate property sheet.
    if criterion_list or getattr(self, 'isEmptyPredicateValid', lambda: True)():
      for criterion in criterion_list:
        if criterion.min and criterion.max:
          catalog_kw[criterion.property] = { 'query' : (criterion.min, criterion.max),
                                             'range' : 'minmax'
                                           }
        elif criterion.min:
          catalog_kw[criterion.property] = { 'query' : criterion.min,
                                             'range' : 'min'
                                           }
        elif criterion.max:
          catalog_kw[criterion.property] = { 'query' : criterion.max,
                                             'range' : 'max'
                                           }
        else:
          # if a filter was passed as argument
          if catalog_kw.has_key(criterion.property):
            if isinstance(catalog_kw[criterion.property], (tuple, list)):
              catalog_filter_set = set(catalog_kw[criterion.property])
            else:
              catalog_filter_set = set([catalog_kw[criterion.property]])
            if isinstance(criterion.identity, (tuple, list)):
              parameter_filter_set = set(criterion.identity)
            else:
              parameter_filter_set = set([criterion.identity])
            catalog_kw[criterion.property] = \
                list(catalog_filter_set.intersection(parameter_filter_set))
          else:
            catalog_kw[criterion.property] = criterion.identity
    else:
      # By catalog definition, no object has uid 0, so this condition forces an
      # empty result.
      catalog_kw['uid'] = 0

    portal_catalog = getToolByName(self, 'portal_catalog')

    from_table_dict = {}

    # First build SQL for membership criteria
    # It would be much nicer if all this was handled by the catalog in a central place
    membership_dict = {}
    for base_category in self.getMembershipCriterionBaseCategoryList():
      membership_dict[base_category] = [] # Init dict with valid base categories
    for category in self.getMembershipCriterionCategoryList():
      base_category = category.split('/')[0] # Retrieve base category
      if membership_dict.has_key(base_category):
        category_value = self._unrestrictedResolveCategory(category, None)
        if category_value is not None:
          table_alias = "single_%s_%s" % (table, base_category)
          from_table_dict[table_alias] = 'category'
          membership_dict[base_category].append(category_value.asSQLExpression(
                                          strict_membership=strict_membership,
                                          table=table_alias,
                                          base_category=base_category))
    membership_select_list = []
    for expression_list in membership_dict.values():
      or_expression = ' OR '.join(expression_list)
      if or_expression:
        membership_select_list.append('( %s )' % or_expression)

    # Then build SQL for multimembership_dict criteria
    multimembership_dict = {}
    for base_category in self.getMultimembershipCriterionBaseCategoryList():
      multimembership_dict[base_category] = [] # Init dict with valid base categories
    join_count = 0
    for category in self.getMembershipCriterionCategoryList():
      base_category = category.split('/')[0] # Retrieve base category
      if multimembership_dict.has_key(base_category):
        category_value = self._unrestrictedResolveCategory(category)
        if category_value is not None:
          join_count += 1
          table_alias = "multi_%s_%s" % (table, join_count)
          from_table_dict[table_alias] = 'category'
          multimembership_dict[base_category].append(category_value.asSQLExpression(
                                          strict_membership=strict_membership,
                                          table=table_alias,
                                          base_category=base_category))
    multimembership_select_list = []
    for expression_list in multimembership_dict.values():
      and_expression = ' AND '.join(expression_list)
      if and_expression:
        multimembership_select_list.append(and_expression)

    # Build the join where expression
    join_select_list = []
    for k in from_table_dict.iterkeys():
      join_select_list.append('%s.%s = %s.uid' % (join_table, join_column, k))

    sql_text = ' AND '.join(join_select_list + membership_select_list +
                            multimembership_select_list)

    # Now merge identity and membership criteria
    if len(sql_text):
      catalog_kw['where_expression'] = SQLQuery(sql_text)
    else:
      catalog_kw['where_expression'] = ''
    # force implicit join
    catalog_kw['implicit_join'] = True
    sql_query = portal_catalog.buildSQLQuery(**catalog_kw)
    # XXX from_table_list is None most of the time after the explicit_join work
    for alias, table in sql_query['from_table_list']:
      if from_table_dict.has_key(alias):
        raise KeyError, "The same table is used twice for an identity criterion and for a membership criterion"
      from_table_dict[alias] = table
    sql_query['from_table_list'] = from_table_dict.items()
    return sql_query
Esempio n. 3
0
    def _searchPredicateList(self,
                             context,
                             test=1,
                             sort_method=None,
                             ignored_category_list=None,
                             tested_base_category_list=None,
                             filter_method=None,
                             acquired=1,
                             strict=True,
                             sort_key_method=None,
                             query=None,
                             restricted=False,
                             **kw):
        # XXX: about "strict" parameter: This is a transition parameter,
        # allowing someone hitting a bug to revert to original behaviour easily.
        # It is not a correct name, as pointed out by Jerome. But instead of
        # searching for another name, it would be much better to just remove it.
        """
      Search all predicates which corresponds to this particular 
      context.

      - sort_method parameter should not be used, if possible, because
        it can be very slow. Use sort_key_method instead.

      - sort_key_method parameter is passed to list.sort as key parameter if it
        is not None. This allows to sort the list of predicates found. The most
        important predicate is the first one in the list.

      - ignored_category_list:  this is the list of category that we do
        not want to test. For example, we might want to not test the 
        destination or the source of a predicate.

      - tested_base_category_list:  this is the list of category that we do
        want to test. For example, we might want to test only the 
        destination or the source of a predicate.

      - the acquired parameter allows to define if we want to use
        acquisition for categories. By default we want.

      - strict: if True, generate SQL which will match predicates matching
        all those categories at the same time, except for categories they do
        not check at all. Example:
          Predicate_1 checks foo/bar
          Predicate_2 checks foo/baz region/somewhere
          Predicate_3 checks foo/bar region/somewhere
          When called with category list ['foo/bar', 'region/somewhere'] and
          strict parameter to True, it will return [Predicate_1, Predicate_3].
          With strict to False or by not giving a category list, it would also
          return Predicate_2, because it matches on one criterion out of the 2
          it checks.
        Note that it changes the value returned by this function if it was
        invoked with "test=False" value. Otherwise, it should only change
        execution duration.
      """
        portal = self.getPortalObject()
        portal_catalog = portal.portal_catalog
        portal_categories = portal.portal_categories
        # Search the columns of the predicate table
        range_column_set = set()
        query_list = [] if query is None else [query]
        for column in portal_catalog.getColumnIds():
            if column[:10] == 'predicate.' and \
               column[-10:] in ('_range_min', '_range_max'):
                property_name = column[10:-10]
                if property_name not in range_column_set:
                    range_column_set.add(property_name)
                    # We have to check a range property
                    equality = 'predicate.' + property_name
                    range_min = equality + '_range_min'
                    range_max = equality + '_range_max'

                    value = context.getProperty(property_name)

                    query = ComplexQuery(Query(**{equality: None}),
                                         Query(**{range_min: None}),
                                         Query(**{range_max: None}),
                                         logical_operator='AND')

                    if value is not None:
                        query = ComplexQuery(
                            query,
                            ComplexQuery(
                                Query(**{equality: value}),
                                ComplexQuery(
                                    ComplexQuery(
                                        Query(
                                            **{
                                                range_min:
                                                dict(
                                                    query=value,
                                                    range='ngt',
                                                )
                                            }),
                                        Query(**{range_max: None}),
                                        logical_operator='AND',
                                    ),
                                    ComplexQuery(
                                        Query(**{range_min: None}),
                                        Query(
                                            **{
                                                range_max:
                                                dict(
                                                    query=value,
                                                    range='min',
                                                )
                                            }),
                                        logical_operator='AND',
                                    ),
                                    ComplexQuery(
                                        Query(
                                            **{
                                                range_min:
                                                dict(
                                                    query=value,
                                                    range='ngt',
                                                )
                                            }),
                                        Query(
                                            **{
                                                range_max:
                                                dict(
                                                    query=value,
                                                    range='min',
                                                )
                                            }),
                                        logical_operator='AND',
                                    ),
                                    logical_operator='OR',
                                ),
                                logical_operator='OR',
                            ),
                            logical_operator='OR')

                    query_list.append(query)

        # Add category selection
        if tested_base_category_list is None:
            if acquired:
                category_list = context.getAcquiredCategoryList()
            else:
                category_list = context.getCategoryList()
        else:
            if acquired:
                getter = context.getAcquiredCategoryMembershipList
            else:
                getter = context.getCategoryMembershipList
            category_list = []
            extend = category_list.extend
            for tested_base_category in tested_base_category_list:
                extend(getter(tested_base_category, base=1))

        if tested_base_category_list != []:
            preferred_predicate_category_list = portal.portal_preferences.getPreferredPredicateCategoryList(
            )

            if (preferred_predicate_category_list
                    and tested_base_category_list is not None
                    and set(preferred_predicate_category_list).issuperset(
                        tested_base_category_list)):
                # New behavior is enabled only if preferred predicate category is
                # defined and tested_base_category_list is passed.
                predicate_category_query_list = []
                predicate_category_table_name_list = []
                category_dict = {}
                for relative_url in category_list:
                    category_value = portal_categories.getCategoryValue(
                        relative_url)
                    base_category_id = portal_categories.getBaseCategoryId(
                        relative_url)
                    base_category_value = portal_categories.getCategoryValue(
                        base_category_id)
                    if not base_category_value in category_dict:
                        category_dict[base_category_value] = []
                    category_dict[base_category_value].append(category_value)

                for base_category_value, category_value_list in category_dict.iteritems(
                ):
                    if base_category_value.getId(
                    ) in preferred_predicate_category_list:
                        table_index = len(predicate_category_query_list)
                        predicate_category_table_name = 'predicate_category_for_domain_tool_%s' % table_index
                        table_alias_list = [('predicate_category',
                                             predicate_category_table_name)]
                        predicate_category_query_list.append(
                            ComplexQuery(
                                Query(predicate_category_base_category_uid=
                                      base_category_value.getUid(),
                                      table_alias_list=table_alias_list),
                                Query(
                                    predicate_category_category_strict_membership
                                    =1,
                                    table_alias_list=table_alias_list),
                                ComplexQuery(
                                    Query(predicate_category_category_uid=[
                                        category_value.getUid() for
                                        category_value in category_value_list
                                    ],
                                          table_alias_list=table_alias_list),
                                    Query(
                                        predicate_category_category_uid='NULL',
                                        table_alias_list=table_alias_list),
                                    logical_operator='OR'),
                                logical_operator='AND'))

                if not predicate_category_query_list:
                    # Prevent matching everything
                    predicate_category_query_list.append(
                        Query(predicate_category_base_category_uid=0))

                predicate_category_query = ComplexQuery(
                    logical_operator='AND', *predicate_category_query_list)
                query_list.append(predicate_category_query)
            else:
                # Traditional behavior
                category_expression_dict = portal_categories.buildAdvancedSQLSelector(
                    category_list or ['NULL'],
                    query_table='predicate_category',
                    none_sql_value=0,
                    strict=strict)
                where_expression = category_expression_dict['where_expression']
                if where_expression:
                    kw['where_expression'] = SQLQuery(where_expression)

                if 'from_expression' in category_expression_dict:
                    kw['from_expression'] = category_expression_dict[
                        'from_expression']
                else:
                    # Add predicate_category.uid for automatic join
                    kw['predicate_category.uid'] = '!=NULL'

        if query_list:
            kw['query'] = ComplexQuery(logical_operator='AND', *query_list)

        if restricted:
            sql_result_list = portal_catalog.searchResults(**kw)
        else:
            sql_result_list = portal_catalog.unrestrictedSearchResults(**kw)
        if kw.get('src__'):
            return sql_result_list
        result_list = []
        for predicate in sql_result_list:
            predicate = predicate.getObject()
            if (not test) or predicate.test(
                    context,
                    tested_base_category_list=tested_base_category_list):
                result_list.append(predicate)
        if filter_method is not None:
            result_list = filter_method(result_list)
        if sort_key_method is not None:
            result_list.sort(key=sort_key_method)
        elif sort_method is not None:
            result_list.sort(cmp=sort_method)
        return result_list