def _hashValues(self): item = self._item kind = item._kind view = item.itsView hash = 0 names = self.keys() names.sort() for name in names: if kind is not None: attribute = kind.getAttribute(name, False, item) else: attribute = None if not self._isTransient(name): hash = _combine(hash, _hash(name)) value = self[name] if attribute is not None: attrType = attribute.type else: attrType = None if attrType is not None: hash = _combine(hash, attrType.hashValue(value)) else: hash = _combine(hash, TypeHandler.hashValue(view, value)) return hash
def _hashValues(self): hash = 0 for key in self.iterkeys(): link = self._get(key) hash = _combine(hash, key._hash) if link.alias is not None: hash = _combine(hash, _hash(link.alias)) return hash
def _hashItem(self): hash = 0 isMixin = self.isMixin() if not isMixin: hash = _combine(hash, _hash(str(self.itsPath))) for superKind in self.getAttributeValue('superKinds', self._references): hash = _combine(hash, superKind.hashItem()) if not isMixin: attributes = list(self.iterAttributes(False)) attributes.sort() for name, attribute, kind in attributes: hash = _combine(hash, _hash(name)) hash = _combine(hash, attribute.hashItem()) return hash
def _hashItem(self): hash = 0 view = self.itsView item = self.getAttributeValue('superAttribute', self._references, None, None) if item is not None: hash = _combine(hash, item.hashItem()) def hashValue(hash, type, value): if type is not None: return _combine(hash, type.hashValue(value)) else: return _combine(hash, TypeHandler.hashValue(view, value)) for aspect in Attribute.valueAspects: value = self.getAttributeValue(aspect, self._values, None, Nil) if value is not Nil: hash = _combine(hash, _hash(aspect)) type = self.getAttributeAspect(aspect, 'type', False, None, None) card = self.getAttributeAspect(aspect, 'cardinality', False, None, 'single') if card == 'single': hash = hashValue(hash, type, value) elif card == 'list': for v in value: hash = hashValue(hash, type, v) else: raise NotImplementedError, card item = self.getAttributeValue('type', self._references, None, None) if item is not None: if isinstance(item, Kind): hash = _combine(hash, _hash(str(item.itsPath))) else: hash = _combine(hash, item.hashItem()) return hash
def _hashValues(self): hash = 0 names = self.keys() names.sort() for name in names: hash = _combine(hash, _hash(name)) value = self[name] if value in (None, Empty): hash = _combine(hash, 0) elif isitem(value): hash = _combine(hash, value._uuid._hash) elif value._isRefs(): hash = _combine(hash, value._hashValues()) else: raise TypeError, value return hash
def hashItem(self): """ Compute a hash value from this aliase's schema. The hash value is computed from the aliase's path and types. @return: an integer """ hash = _hash(str(self.itsPath)) if 'types' in self._references: for t in self.types: hash = _combine(hash, t.hashItem()) return hash
def mixin(self, superKinds): """ Find or generate a mixin kind. The mixin kind is defined as the combination of this kind and the additional kind items specified with C{superKinds}. A new kind is generated if the corresponding mixin kind doesn't yet exist. The item class of the resulting mixin kind is a composite of the superKinds' item classes. See L{getItemClass} for more information. @param superKinds: the kind items added to this kind to form the mixin @type superKinds: list @return: a L{Kind<chandlerdb.schema.Kind.Kind>} instance """ duplicates = {} for superKind in superKinds: if superKind.itsUUID in duplicates: raise ValueError, 'Kind %s is duplicated' %(superKind.itsPath) else: duplicates[superKind.itsUUID] = superKind hash = self.hashItem() for superKind in superKinds: hash = _combine(hash, superKind.hashItem()) if hash < 0: hash = ~hash name = "mixin_%08x" %(hash) parent = self.getItemKind().itsParent['Mixins'] kind = parent.getItemChild(name) if kind is None: kind = self.itsKind.newItem(name, parent) kind.addValue('superKinds', self) kind.superKinds.extend(superKinds) kind.mixins = [sk.itsPath for sk in kind.superKinds] return kind
def mixin(self, superKinds): """ Find or generate a mixin kind. The mixin kind is defined as the combination of this kind and the additional kind items specified with C{superKinds}. A new kind is generated if the corresponding mixin kind doesn't yet exist. The item class of the resulting mixin kind is a composite of the superKinds' item classes. See L{getItemClass} for more information. @param superKinds: the kind items added to this kind to form the mixin @type superKinds: list @return: a L{Kind<chandlerdb.schema.Kind.Kind>} instance """ duplicates = {} for superKind in superKinds: if superKind.itsUUID in duplicates: raise ValueError, 'Kind %s is duplicated' % (superKind.itsPath) else: duplicates[superKind.itsUUID] = superKind hash = self.hashItem() for superKind in superKinds: hash = _combine(hash, superKind.hashItem()) if hash < 0: hash = ~hash name = "mixin_%08x" % (hash) parent = self.getItemKind().itsParent['Mixins'] kind = parent.getItemChild(name) if kind is None: kind = self.itsKind.newItem(name, parent) kind.addValue('superKinds', self) kind.superKinds.extend(superKinds) kind.mixins = [sk.itsPath for sk in kind.superKinds] return kind
def getItemClass(self): """ Return the class used to create items of this Kind. If this Kind has superKinds and C{self.classes['python']} is not set a composite class is generated and cached from the superKinds. The L{Item<chandlerdb.item.Item.Item>} class is returned by default. """ missing = False try: cls = self._values['classes']['python'] if cls is not MissingClass: return cls missing = True except KeyError: pass except TypeError: pass superClasses = [] for superKind in self._references.get('superKinds', Nil): c = superKind.getItemClass() if c is not Item and c not in superClasses: superClasses.append(c) count = len(superClasses) if count == 0: c = self.itsView.classLoader.getItemClass() elif count == 1: c = superClasses[0] else: # Filter out redundant superclasses that may cause MRO wonkiness. # A redundant superclass is one with a subclass occurring later # in the superclass list. classes = superClasses superClasses = [] while classes: cls = classes.pop(0) for c in classes: if issubclass(c, cls): break else: superClasses.append(cls) hash = 0 for c in superClasses: hash = _combine(hash, _hash('.'.join((c.__module__, c.__name__)))) if hash < 0: hash = ~hash name = "class_%08x" %(hash) c = classobj(name, tuple(superClasses), {}) self._values['classes'] = { 'python': c } self._values._setTransient('classes') self._setupClass(c) if missing: self.itsView.logger.warn('Missing class for Kind %s replaced by %s.%s', self.itsPath, c.__module__, c.__name__) return c
def hashValue(hash, type, value): if type is not None: return _combine(hash, type.hashValue(value)) else: return _combine(hash, TypeHandler.hashValue(view, value))
def getItemClass(self): """ Return the class used to create items of this Kind. If this Kind has superKinds and C{self.classes['python']} is not set a composite class is generated and cached from the superKinds. The L{Item<chandlerdb.item.Item.Item>} class is returned by default. """ missing = False try: cls = self._values['classes']['python'] if cls is not MissingClass: return cls missing = True except KeyError: pass except TypeError: pass superClasses = [] for superKind in self._references.get('superKinds', Nil): c = superKind.getItemClass() if c is not Item and c not in superClasses: superClasses.append(c) count = len(superClasses) if count == 0: c = self.itsView.classLoader.getItemClass() elif count == 1: c = superClasses[0] else: # Filter out redundant superclasses that may cause MRO wonkiness. # A redundant superclass is one with a subclass occurring later # in the superclass list. classes = superClasses superClasses = [] while classes: cls = classes.pop(0) for c in classes: if issubclass(c, cls): break else: superClasses.append(cls) hash = 0 for c in superClasses: hash = _combine(hash, _hash('.'.join((c.__module__, c.__name__)))) if hash < 0: hash = ~hash name = "class_%08x" % (hash) c = classobj(name, tuple(superClasses), {}) self._values['classes'] = {'python': c} self._values._setTransient('classes') self._setupClass(c) if missing: self.itsView.logger.warn( 'Missing class for Kind %s replaced by %s.%s', self.itsPath, c.__module__, c.__name__) return c