Beispiel #1
0
    def traverse_one(self, attribute, source, target, visitor):
        """
        :param source: source data proxy
        :type source: instance of `DataTraversalProxy` or None
        :param target: target data proxy
        :type target: instance of `DataTraversalProxy` or None
        """
        if __debug__:
            self.__log_traverse_one(self.__trv_path, attribute, source, target)
        prx = source or target
        if prx.do_traverse():
            rel_op = RELATION_OPERATIONS.check(source, target)
            for attr in prx.get_relationship_attributes():
                # Check cascade settings.
                if not bool(attr.cascade & rel_op):
                    continue
                if not source is None:
                    try:
                        attr_source = source.get_attribute_proxy(attr)
                    except AttributeError:
                        # If the source does not have the attribute set, we
                        # do nothing (as opposed to when the value is None).
                        continue
                else:
                    attr_source = None
                if not target is None:
                    attr_target = target.get_attribute_proxy(attr)
                else:
                    attr_target = None
                attr_rel_op = RELATION_OPERATIONS.check(attr_source,
                                                        attr_target)
                if attr_rel_op == RELATION_OPERATIONS.ADD:
                    if rel_op == RELATION_OPERATIONS.ADD:
                        parent = source
                    else:
                        parent = target
                elif attr_rel_op == RELATION_OPERATIONS.REMOVE:
                    parent = target
                else: # UPDATE
                    parent = target
                card = get_attribute_cardinality(attr)
                if card == CARDINALITY_CONSTANTS.ONE:
                    if attr_source is None and attr_target is None:
                        # If both source and target have None values, there is
                        # nothing to do.
                        continue
                    if attr_rel_op == RELATION_OPERATIONS.ADD:
#                        if not attr_source.get_id() is None:
#                            # We only ADD new items.
#                            continue
                        src_items = [attr_source]
                        tgt_items = None
                    elif attr_rel_op == RELATION_OPERATIONS.REMOVE:
                        src_items = None
                        tgt_items = [attr_target]
                    else: # UPDATE
                        src_items = [attr_source]
                        tgt_items = [attr_target]
                        src_id = attr_source.get_id()
                        tgt_id = attr_target.get_id()
                        if src_id != tgt_id:
                            if not src_id is None:
                                # If the source ID is None, this is a replace
                                # operation (ADD source, REMOVE target).
                                src_target = attr_target.get_matching(src_id)
                                if not src_target is None:
                                    tgt_items.append(src_target)
                else:
                    src_items = attr_source
                    tgt_items = attr_target
                self.__trv_path.push(parent, (source, target), attr, rel_op)
                self.traverse_many(attr, src_items, tgt_items, visitor)
                self.__trv_path.pop() # path.pop()
        visitor.visit(self.__trv_path, attribute, source, target)
Beispiel #2
0
 def test_get_attribute_cardinality(self):
     self.assert_equal(get_attribute_cardinality(self.member_attr),
                       CARDINALITY_CONSTANTS.ONE)
     self.assert_raises(ValueError, get_attribute_cardinality,
                        self.terminal_attr)
Beispiel #3
0
 def test_get_attribute_cardinality(self, attr_name):
     mb_attr = member_attribute(Member, attr_name)
     assert get_attribute_cardinality(mb_attr) == CARDINALITY_CONSTANTS.ONE
     t_attr = terminal_attribute(int, attr_name)
     with pytest.raises(ValueError):
         get_attribute_cardinality(t_attr)
Beispiel #4
0
 def test_get_attribute_cardinality(self, attr_name):
     mb_attr = member_attribute(Member, attr_name)
     assert get_attribute_cardinality(mb_attr) == CARDINALITY_CONSTANTS.ONE
     t_attr = terminal_attribute(int, attr_name)
     with pytest.raises(ValueError):
         get_attribute_cardinality(t_attr)
Beispiel #5
0
 def traverse_one(self, attribute, source, target, visitor):
     """
     :param source: source data proxy
     :type source: instance of `DataTraversalProxy` or None
     :param target: target data proxy
     :type target: instance of `DataTraversalProxy` or None
     """
     if __debug__:
         self.__log_traverse_one(self.__trv_path, attribute, source, target)
     prx = source or target
     rel_op = RELATION_OPERATIONS.check(source, target)
     if prx.do_traverse() \
        and (rel_op == prx.relation_operation or attribute is None):
         for attr in prx.get_relationship_attributes():
             # Check cascade settings.
             if not bool(attr.cascade & rel_op):
                 continue
             if not source is None:
                 try:
                     attr_source = source.get_attribute_proxy(attr)
                 except AttributeError:
                     # If the source does not have the attribute set, we
                     # do nothing (as opposed to when the value is None).
                     continue
             else:
                 attr_source = None
             if not target is None:
                 attr_target = target.get_attribute_proxy(attr)
             else:
                 attr_target = None
             attr_rel_op = RELATION_OPERATIONS.check(
                 attr_source, attr_target)
             if attr_rel_op == RELATION_OPERATIONS.ADD:
                 if rel_op == RELATION_OPERATIONS.ADD:
                     parent = source
                 else:
                     parent = target
             elif attr_rel_op == RELATION_OPERATIONS.REMOVE:
                 parent = target
             else:  # UPDATE
                 parent = target
             card = get_attribute_cardinality(attr)
             if card == CARDINALITY_CONSTANTS.ONE:
                 if attr_source is None and attr_target is None:
                     # If both source and target have None values, there is
                     # nothing to do.
                     continue
                 if attr_rel_op == RELATION_OPERATIONS.ADD:
                     #                        if not attr_source.get_id() is None:
                     #                            # We only ADD new items.
                     #                            continue
                     src_items = [attr_source]
                     tgt_items = None
                 elif attr_rel_op == RELATION_OPERATIONS.REMOVE:
                     src_items = None
                     tgt_items = [attr_target]
                 else:  # UPDATE
                     src_items = [attr_source]
                     tgt_items = [attr_target]
                     src_id = attr_source.get_id()
                     tgt_id = attr_target.get_id()
                     if src_id != tgt_id:
                         if not src_id is None:
                             # If the source ID is None, this is a replace
                             # operation (ADD source, REMOVE target).
                             src_target = attr_target.get_matching(src_id)
                             if not src_target is None:
                                 tgt_items.append(src_target)
             else:
                 src_items = attr_source
                 tgt_items = attr_target
             self.__trv_path.push(parent, (source, target), attr, rel_op)
             self.traverse_many(attr, src_items, tgt_items, visitor)
             self.__trv_path.pop()  # path.pop()
     visitor.visit(self.__trv_path, attribute, source, target)