Exemplo n.º 1
0
    def attrs(self, *args, **kwargs):
        """Return attributes for this entity.

        (filters whole attribute list as opposed to querying the db directly)
        """

        merge_container_attrs = kwargs.pop('merge_container_attrs', False)
        ignore_memcache = kwargs.pop('ignore_memcache', False)

        if clusto.SESSION.memcache and not ignore_memcache:
            logging.debug('Pulling info from memcache when possible for %s' % self.name)
            k = None
            if 'key' in kwargs:
                k = kwargs['key']
            else:
                if len(args) > 1:
                    k = args[0]
            if k:
#               This is hackish, need to find another way to know if we should cache things or not
                if not k.startswith('_'):
                    if 'subkey' in kwargs and kwargs['subkey'] is not None:
                        memcache_key = str('%s.%s.%s' % (self.name, k, kwargs['subkey']))
                    else:
                        memcache_key = str('%s.%s' % (self.name, k))
                    logging.debug('memcache key: %s' % memcache_key)
                    attrs = clusto.SESSION.memcache.get(memcache_key)
                    if not attrs:
                        attrs = self.attr_filter(self.entity.attrs, *args, **kwargs)
                        if attrs:
                            clusto.SESSION.memcache.set(memcache_key, attrs)
                else:
                    attrs = self.attr_filter(self.entity.attrs, *args, **kwargs)
            else:
                logging.debug('We cannot cache attrs without a key at least')
                attrs = self.attr_filter(self.entity.attrs, *args, **kwargs)
        else:
            attrs = self.attr_filter(self.entity.attrs, *args, **kwargs)

        if merge_container_attrs:
            kwargs['merge_container_attrs'] = merge_container_attrs
            kwargs['ignore_memcache'] = ignore_memcache
            parent_entity_ids = [parent.entity.entity_id for parent in self.parents()]
            while parent_entity_ids:
                parent_attrs = Attribute.query().filter(
                    Attribute.entity_id.in_(parent_entity_ids)).all()
                attrs.extend(parent_attrs)
                grandparent_contains_attributes = Attribute.query().filter(
                    Attribute.relation_id.in_(parent_entity_ids)).filter(
                    Attribute.key == '_contains').all()
                parent_entity_ids = [a.entity_id for a in grandparent_contains_attributes]
            kwargs.pop('merge_container_attrs')
            kwargs.pop('ignore_memcache')
            attrs = self.attr_filter(attrs, *args, **kwargs)
        return attrs
Exemplo n.º 2
0
    def contents(self, *args, **kwargs):
        """Return the contents of this Entity.  Such that:

        >>> A.insert(B)
        >>> A.insert(C)
        >>> A.contents()
        [B, C]

        """

        if 'search_children' in kwargs:
            search_children = kwargs.pop('search_children')
        else:
            search_children = False

        contents = self._get_contents(*args, **kwargs)

        if search_children:
            # We want to prune our search so that children that do not have children do not need to
            # be searched. To do so, we query for children that have a _contains attribute, and only
            # call .contents() on those children.
            children = self._get_contents()
            children_entity_ids = [child.entity.entity_id for child in children]

            if children_entity_ids:
                contains_attributes = Attribute.query().filter(
                    Attribute.key == '_contains').filter(
                    Attribute.entity_id.in_(children_entity_ids)).all()
            else:
                contains_attributes = []

            child_entity_ids_to_search = set([attr.entity_id for
                                              attr in contains_attributes])
            children_to_search = [child for child in children if
                                  child.entity.entity_id in child_entity_ids_to_search]

            for child in children_to_search:
                kwargs['search_children'] = search_children
                contents.extend(child.contents(*args, **kwargs))

        return contents
Exemplo n.º 3
0
    def do_attr_query(cls, key=(), value=(), number=(), start_timestamp=(), end_timestamp=(),
                      subkey=(), ignore_hidden=True, sort_by_keys=False,
                      glob=False, count=False, querybase=None, return_query=False,
                      entity=None):
        """Does queries against all Attributes using the DB."""

        clusto.flush()
        if querybase:
            query = querybase
        else:
            query = Attribute.query()

        ### This is bunk, gotta fix it
        if isinstance(cls, Driver):
            query = query.filter(and_(Attribute.entity_id == Entity.entity_id,
                                      Entity.driver == cls._driver_name,
                                      Entity.type == cls._clusto_type))

        if start_timestamp != () and end_timestamp != ():
            query = query.filter(and_((Attribute.datetime_value >= start_timestamp)))
            query = query.filter(and_(Attribute.datetime_value <= end_timestamp))

        if entity:
            query = query.filter_by(entity_id=entity.entity_id)

        if key is not ():
            key = unicode(key)

            if glob:
                query = query.filter(Attribute.key.like(key.replace('*', '%')))
            else:
                query = query.filter_by(key=key)

        if subkey is not ():
            if subkey is not None:
                subkey = unicode(subkey)

            if glob and subkey:
                query = query.filter(Attribute.subkey.like(subkey.replace('*', '%')))
            else:
                query = query.filter_by(subkey=subkey)

        if value is not ():
            typename = Attribute.get_type(value)

            if typename == 'relation':
                if isinstance(value, Driver):
                    value = value.entity.entity_id
                query = query.filter_by(relation_id=value)
            else:
                if typename == 'json':
                    typename = 'string'
                    value = json.dumps(value)

                if typename == 'string':
                    value = unicode(value)

                query = query.filter_by(**{typename+'_value': value})

        if number is not ():
            if isinstance(number, bool) or number is None:
                if number:
                    query = query.filter(Attribute.number != None)  # noqa
                else:
                    query = query.filter(Attribute.number == None)  # noqa
            elif isinstance(number, (int, long)):
                query = query.filter_by(number=number)

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

        if ignore_hidden and ((key and not key.startswith('_')) or key is ()):
            query = query.filter(not_(Attribute.key.like(u'@_%', escape=u'@')))

        if sort_by_keys:
            query = query.order_by(Attribute.key)

        if count:
            return query.count()

        if return_query:
            return query

        return query.all()