def __delitem__(self, key): """We do a cascade delete of everything that *must* be linked to us. We don't need to bother about deleting links because the delete hooks on entity_store do this automatically.""" if not self.entity_store.start_deleting_entity(key): # we're already being deleted so do nothing return try: for linkEnd, navName in self.entity_set.linkEnds.iteritems(): if linkEnd.associationEnd.multiplicity != edm.Multiplicity.One: continue # there must be one of us, delete the other end with # the exception that if there is no navigation property # bound to this property then we won't do a cascade delete # We have to go straight to the storage layer to sort # this out. We are allowed to raise # edm.NavigationConstraintError here but then it would # be impossible to delete 1-1 related entities which is # a bit limited as_name = linkEnd.parent.name aindex = self.entity_store.associations.get( linkEnd.parent.name, None) if aindex: with aindex.to_store.entity_set.OpenCollection() as \ toCollection: for to_key in aindex.get_links_from(key): if navName is None and \ not aindex.to_store.deleting(to_key): # if we are not in the process of # deleting to_key and there is no # navigation property linking us to it # then raise an error raise edm.NavigationConstraintError( "Can't cascade delete from an entity in " "%s as the association set %s is not " "bound to a navigation property" % (self.entity_set.name, as_name)) # delete this link first to prevent infinite # recursion aindex.remove_link(key, to_key) del toCollection[to_key] else: aindex = self.entity_store.reverseAssociations.get( linkEnd.parent.name, None) with aindex.from_store.entity_set.OpenCollection() as \ from_collection: for from_key in aindex.get_links_to(key): if navName is None and not \ aindex.from_store.deleting(from_key): raise edm.NavigationConstraintError( "Can't cascade delete from an entity in " "%s as the association set %s is not " "bound to a navigation property" % (self.entity_set.name, as_name)) aindex.remove_link(from_key, key) del from_collection[from_key] self.entity_store.delete_entity(key) finally: self.entity_store.stop_deleting(key)
def __delitem__(self, key): """We do a cascade delete of everything that *must* be linked to us. We don't need to bother about deleting links because the delete hooks on entityStore do this automatically.""" if not self.entityStore.StartDeletingEntity(key): # we're already being deleted so do nothing return try: for linkEnd, navName in self.entitySet.linkEnds.iteritems(): if linkEnd.associationEnd.multiplicity == edm.Multiplicity.One: # there must be one of us, delete the other end with # the exception that if there is no navigation property # bound to this property then we won't do a cascade delete # We have to go straight to the storage layer to sort # this out. We are allowed to raise # edm.NavigationConstraintError here but then it would # be impossible to delete 1-1 related entities which is # a bit limited associationSetName = linkEnd.parent.name associationIndex = self.entityStore.associations.get( linkEnd.parent.name, None) if associationIndex: with associationIndex.toEntityStore.entitySet.OpenCollection( ) as toCollection: for toKey in associationIndex.GetLinksFrom(key): if navName is None and not associationIndex.toEntityStore.DeletingEntity( toKey): # if we are not in the process of deleting toKey # and there is no navigation property linking us # to it then raise an error raise edm.NavigationConstraintError( "Can't cascade delete from an entity in %s as the association set %s is not bound to a navigation property" % (self.entitySet.name, associationSetName)) # delete this link first to prevent infinite # recursion associationIndex.RemoveLink(key, toKey) del toCollection[toKey] else: associationIndex = self.entityStore.reverseAssociations.get( linkEnd.parent.name, None) with associationIndex.fromEntityStore.entitySet.OpenCollection( ) as fromCollection: for fromKey in associationIndex.GetLinksTo(key): if navName is None and not associationIndex.fromEntityStore.DeletingEntity( fromKey): raise edm.NavigationConstraintError( "Can't cascade delete from an entity in %s as the association set %s is not bound to a navigation property" % (self.entitySet.name, associationSetName)) associationIndex.RemoveLink(fromKey, key) del fromCollection[fromKey] self.entityStore.DeleteEntity(key) finally: self.entityStore.StopDeletingEntity(key)
def replace(self, entity): key = entity.key() result_set = list(self.lookupMethod(self.key)) if result_set == [key]: # nothing to do! return if self.fromMultiplicity == edm.Multiplicity.One: if result_set: # we can't delete these links because we are required raise edm.NavigationConstraintError( "Can't remove a required link") else: self[key] = entity else: # add the new link first if key not in result_set: if self.reverse: self.aindex.add_link(key, self.key) else: self.aindex.add_link(self.key, key) for oldKey in result_set: # now remove all the old keys. This implementation # is the same regardless of the allowed multiplicity. # This doesn't just save coding, it ensures that # corrupted indexes are self-correcting if oldKey != key: if self.reverse: self.aindex.remove_link(oldKey, self.key) else: self.aindex.remove_link(self.key, oldKey)
def __setitem__(self, key, value): result_set = self.lookupMethod(self.key) if key in result_set: # no operation return # forces a check of value to ensure it is good self.collection[key] = value if self.toMultiplicity != edm.Multiplicity.Many: if result_set: raise edm.NavigationConstraintError( "Can't add multiple links to navigation property %s" % self.name) if self.fromMultiplicity != edm.Multiplicity.Many: if self.rLookupMethod(key): raise edm.NavigationConstraintError( "Entity %s is already bound through this association" % value.get_location()) # clear to add this one to the index if self.reverse: self.aindex.add_link(key, self.key) else: self.aindex.add_link(self.key, key)
def __delitem__(self, key): # Before we remove a link we need to know if either entity # requires a link, if so, this deletion will result in a # constraint violation if self.fromMultiplicity == edm.Multiplicity.One or self.toMultiplicity == edm.Multiplicity.One: raise edm.NavigationConstraintError("Can't remove a required link") resultSet = self.lookupMethod(self.key) if key not in resultSet: raise KeyError if self.reverse: self.associationIndex.RemoveLink(key, self.key) else: self.associationIndex.RemoveLink(self.key, key)