def process_function(self, node): assert isinstance(node, UpdateExpressionFunction) function_name = node.get_function_name() first_arg = node.get_nth_argument(1) second_arg = node.get_nth_argument(2) if function_name == "if_not_exists": if isinstance(first_arg, NoneExistingPath): result = second_arg else: result = first_arg assert isinstance(result, (DDBTypedValue, NoneExistingPath)) return result elif function_name == "list_append": first_arg = deepcopy( self.get_list_from_ddb_typed_value(first_arg, function_name)) second_arg = self.get_list_from_ddb_typed_value( second_arg, function_name) for list_element in second_arg.value: first_arg.value.append(list_element) return DDBTypedValue(first_arg) else: raise NotImplementedError( "Unsupported function for moto {name}".format( name=function_name))
def replace_expression_attribute_value_with_value(self, node): """A node representing an Expression Attribute Value. Resolve and replace value""" assert isinstance(node, ExpressionAttributeValue) attribute_value_name = node.get_value_name() try: target = self.expression_attribute_values[attribute_value_name] except KeyError: raise ExpressionAttributeValueNotDefined( attribute_value=attribute_value_name) return DDBTypedValue(DynamoType(target))
def get_subtraction(cls, left_operand, right_operand): """ Args: left_operand(DynamoType): right_operand(DynamoType): Returns: DDBTypedValue: """ try: return DDBTypedValue(left_operand - right_operand) except TypeError: raise IncorrectOperandType("-", left_operand.type)
def resolve_expression_path_nodes(self, item, update_expression_path_nodes): target = item.attrs for child in update_expression_path_nodes: # First replace placeholder with attribute_name attr_name = None if isinstance(child, ExpressionAttributeName): attr_placeholder = child.get_attribute_name_placeholder() try: attr_name = self.expression_attribute_names[ attr_placeholder] except KeyError: raise ExpressionAttributeNameNotDefined(attr_placeholder) elif isinstance(child, ExpressionAttribute): attr_name = child.get_attribute_name() self.raise_exception_if_keyword(attr_name) if attr_name is not None: # Resolv attribute_name try: target = target[attr_name] except (KeyError, TypeError): if child == update_expression_path_nodes[-1]: return NoneExistingPath(creatable=True) return NoneExistingPath() else: if isinstance(child, ExpressionPathDescender): continue elif isinstance(child, ExpressionSelector): index = child.get_index() if target.is_list(): try: target = target[index] except IndexError: # When a list goes out of bounds when assigning that is no problem when at the assignment # side. It will just append to the list. if child == update_expression_path_nodes[-1]: return NoneExistingPath(creatable=True) return NoneExistingPath() else: raise InvalidUpdateExpressionInvalidDocumentPath else: raise NotImplementedError( "Path resolution for {t}".format(t=type(child))) if not isinstance(target, DynamoType): print(target) return DDBTypedValue(target)