def testDriverSearches(self): d = Driver('d1') self.assertRaises(NameError, clusto.get_driver_name, 'FAKEDRIVER') self.assertEqual(clusto.get_driver_name(Driver), 'entity') self.assertRaises(LookupError, clusto.get_driver_name, 123) self.assertEqual(clusto.get_driver_name('entity'), 'entity') self.assertEqual(clusto.get_driver_name(d.entity), 'entity')
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) if clusto_drivers: cdl = [clusto.get_driver_name(n) for n in clusto_drivers] result = (attr for attr in result if attr.entity.driver in cdl) if clusto_types: ctl = [clusto.get_type_name(n) for n in clusto_types] result = (attr for attr in result if attr.entity.type in ctl) return list(result)
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)
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] result = (attr for attr in result if attr.is_relation and attr.value.entity.driver in cdl) if clusto_types: ctl = [clusto.get_type_name(n) for n in clusto_types] result = (attr for attr in result if attr.is_relation and attr.value.entity.type in ctl) if sort_by_keys: result = sorted(result) return list(result)