Example #1
0
    def references(self, *args, **kwargs):
        """Return the references to this Thing. The references are attributes.

        Accepts the same arguments as attrs().

        The semantics of clusto_types and clusto_drivers changes to match the
        clusto_type or clusto_driver of the Entity that owns the attribute as
        opposed to the Entity the attribute refers to.
        """
        clusto_drivers = kwargs.pop('clusto_drivers', None)
        clusto_types = kwargs.pop('clusto_types', None)

        result = self.attr_filter(self.entity.references, *args, **kwargs)

        attribute_entity_ids = [attr.entity_id for attr in result]

        if not attribute_entity_ids:
            return []

        if clusto_drivers:
            cdl = [clusto.get_driver_name(n) for n in clusto_drivers]
            entities = Entity.query().filter(
                Entity.entity_id.in_(attribute_entity_ids)).filter(
                Entity.driver.in_(cdl)).all()
            valid_entity_ids = set([e.entity_id for e in entities])

            result = (attr for attr in result if attr.entity_id in valid_entity_ids)

        if clusto_types:
            ctl = [clusto.get_type_name(n) for n in clusto_types]
            entities = Entity.query().filter(
                Entity.entity_id.in_(attribute_entity_ids)).filter(
                Entity.type.in_(ctl)).all()
            valid_entity_ids = set([e.entity_id for e in entities])

            result = (attr for attr in result if attr.entity_id in valid_entity_ids)

        return list(result)
Example #2
0
    def _get_contents(self, *args, **kwargs):
        contents_entity_ids = [attr.relation_id for attr in self.content_attrs(*args, **kwargs)]

        # sqlalchemy generates a bad query if you pass an empty list to an in_
        # clause
        contents_entities = []
        if contents_entity_ids:
            # Query for 500 elements at a time
            for batch_iterator in batch(contents_entity_ids, 500):
                contents_entities.extend(Entity.query().filter(
                    Entity.entity_id.in_(list(batch_iterator))).all())
        else:
            contents_entities = []
        contents = [Driver(e) for e in contents_entities]

        return contents
Example #3
0
    def referencers(self, *args, **kwargs):
        """Return the Things that reference _this_ Thing.

        Accepts the same arguments as references() but adds an instanceOf filter
        argument.
        """

        referencing_entity_ids = [a.entity_id for a in sorted(self.references(*args, **kwargs),
                                                              lambda x, y: cmp(x.attr_id,
                                                                               y.attr_id))]
        if not referencing_entity_ids:
            return []

        # This kinda sucks
        sorting_dict = dict((entity_id, idx)
                            for idx, entity_id in enumerate(referencing_entity_ids))
        referencing_entities = Entity.query().filter(
            Entity.entity_id.in_(referencing_entity_ids)).all()
        refs = sorted([Driver(e) for e in referencing_entities],
                      key=lambda d: sorting_dict[d.entity.entity_id])
        return refs
Example #4
0
    def attr_filter(cls, attrlist, key=(), value=(), number=(),
                    subkey=(), ignore_hidden=True,
                    sort_by_keys=True,
                    regex=False,
                    clusto_types=None,
                    clusto_drivers=None,
                    ):
        """Filter attribute lists. (Uses generator comprehension)

        Given a list of Attributes filter them based on exact matches of key,
        number, subkey, value.

        There are some special cases:

        if number is True then the number variable must be non-null. if
        number is False then the number variable must be null.

        if ignore_hidden is True (the default) then filter out keys that begin
        with an underscore, if false don't filter out such keys.  If you
        specify a key that begins with an underscore as one of the arguments
        then ignore_hidden is assumed to be False.

        if sort_by_keys is True then attributes are returned sorted by keys,
        otherwise their order is undefined.

        if regex is True then treat the key, subkey, and value query
        parameters as regular expressions.

        clusto_types is a list of types that the entities referenced by
        relation attributes must match.

        clusto_drivers is a list of drivers that the entities referenced by
        relation attributes must match.
        """

        result = attrlist

        def subfilter(attrs, val, name):

            if regex:
                testregex = re.compile(val)
                result = (attr for attr in attrs
                          if testregex.match(getattr(attr, name)))

            else:
                result = (attr for attr in attrs
                          if getattr(attr, name) == val)

            return result

        parts = ((key, 'key'), (subkey, 'subkey'), (value, 'value'))
        argattr = ((val, name) for val, name in parts if val is not ())

        for v, n in argattr:
            result = subfilter(result, v, n)

        if number is not ():
            if isinstance(number, bool) or number is None:
                if number:
                    result = (attr for attr in result if attr.number is not None)
                else:
                    result = (attr for attr in result if attr.number is None)

            elif isinstance(number, (int, long)):
                result = (attr for attr in result if attr.number == number)

            else:
                raise TypeError("number must be either a boolean or an integer.")

        if value:
            result = (attr for attr in result if attr.value == value)

        if key and key.startswith('_'):
            ignore_hidden = False

        if ignore_hidden:
            result = (attr for attr in result if not attr.key.startswith('_'))

        if clusto_drivers:
            cdl = [clusto.get_driver_name(n) for n in clusto_drivers]
            relation_attrs = [relation_attr for relation_attr in result if
                              relation_attr.is_relation]
            if relation_attrs:
                related_entities = Entity.query().filter(
                    Entity.entity_id.in_([relation_attr.relation_id for relation_attr in
                                          relation_attrs])).filter(Entity.driver.in_(cdl)).all()
                related_entity_ids = set([e.entity_id for e in related_entities])
                result = (attr for attr in relation_attrs if attr.relation_id in related_entity_ids)
            else:
                result = []

        if clusto_types:
            ctl = [clusto.get_type_name(n) for n in clusto_types]
            relation_attrs = [relation_attr for relation_attr in result if
                              relation_attr.is_relation]
            if relation_attrs:
                related_entities = Entity.query().filter(
                    Entity.entity_id.in_([relation_attr.relation_id for relation_attr in
                                          relation_attrs])).filter(
                    Entity.type.in_(ctl)).all()
                related_entity_ids = set([e.entity_id for e in related_entities])
                result = (attr for attr in relation_attrs if attr.relation_id in related_entity_ids)
            else:
                result = []

        if sort_by_keys:
            result = sorted(result)

        return list(result)