def check_key_in_operator_fields(key): '''Check whether the field name in '$set' is validated.''' name_list = key.split('.') name_error = NameError("%s is an illegal key!", key) for name in name_list: if not (util.legal_variable_name(name) or name.isdigit() or name == '$'): raise name_error if name_list.count('$') > 1: raise name_error if not util.legal_variable_name(name_list[0]): raise name_error if (name_list.count('$') == 1 and name_list[name_list.index('$') - 1].isdigit()): raise name_error return name_list
def __check_value(self, field, name, value): '''Validate the value. :Parameters: - `field`: Field the value is assigned to. - `name`: Name of the field in document. - `value`: value to be validated. ''' value = field.validate(value) if (field.unique and not field.in_list and util.legal_variable_name(name)): count = self.collection.find({name: value}).count() if count: raise UniqueError(field=name) return value
def __new__(cls, name, bases, attrs): new_class = type.__new__(cls, name, bases, attrs) for base in reversed(inspect.getmro(new_class)): for name, attr in base.__dict__.items(): if isinstance(attr, Field): if not util.legal_variable_name(name): raise FieldNameError(field=name) elif isinstance(attr, MonguoOperation): new_attr = attr.bound_method(name) setattr(new_class, name, new_attr) elif isinstance(attr, types.FunctionType): new_attr = staticmethod(attr) setattr(new_class, name, new_attr) return new_class
def validate_document(cls, document): '''Validate the given document. :Parameters: - `document`: The document to be validated. ''' if not isinstance(document, dict): raise TypeError("Argument 'document' should be dict type.") _document = {} fields_dict = cls.fields_dict() for name, attr in document.items(): if not util.legal_variable_name(name): raise NameError("%s named error." % name) if name not in fields_dict: raise UndefinedFieldError(field=name) for name, attr in fields_dict.items(): if (attr.required and not document.has_key(name) and attr.default is None): raise RequiredError(field=name) value = None if (attr.required and not document.has_key(name) and attr.default is not None): value = attr.default elif document.has_key(name): value = document[name] if value is not None: if not isinstance(attr, DictField): value = attr.validate(value) else: value = attr.document.validate_document(value) _document[name] = value return _document
def deal_with_operator(operator): for name, value in document[operator].items(): value = pre_deal(operator, value) original_name = name name_list = check_key_in_operator_fields(name) name_without_dollar = '.'.join( [name for name in name_list if name != '$']) fields_dict = self.document_cls.fields_dict() if name_list[0] not in fields_dict: raise UndefinedFieldError(field=name_list[0]) current_attr = fields_dict[name_list[0]] if operator == '$unset': last_name = name_list.pop() if not name_list: fields_dict = self.document_cls.fields_dict() if name in fields_dict and fields_dict[name].required: raise FieldDeleteError(field=name) for index, name in enumerate(name_list): if name == '$' or name.isdigit(): if index != len(name_list) - 1: next_name = name_list[index + 1] if next_name.isdigit(): if isinstance(current_attr, ListField): current_attr = current_attr.field elif isinstance(current_attr, GenericListField): break else: raise TypeError( "item in %s should be GenericListField " "or ListField type." % name) else: if isinstance(current_attr.field, DictField): current_attr = current_attr.field elif isinstance(current_attr.field, GenericDictField): break else: raise TypeError( "item in %s should be GenericDictField " "or DictField type." % name) else: if operator == '$unset': post_deal(operator, current_attr, last_name, value) else: post_deal(operator, current_attr, name_without_dollar, value) result = self.__check_value( current_attr, name_without_dollar, value['value']) if value.has_key('each'): if value['each']: document[operator][original_name]['$each'] = result else: document[operator][original_name] = result[0] else: document[operator][original_name] = result else: if index != len(name_list) - 1: next_name = name_list[index + 1] if util.legal_variable_name(next_name): if isinstance(current_attr, DictField): current_attr = current_attr.document.fields_dict()[next_name] elif isinstance(current_attr, GenericDictField): break else: raise TypeError( "'%s' isn't DictField or GenericDictField type." % name) else: if isinstance(current_attr, ListField): current_attr = current_attr.field elif isinstance(current_attr, GenericListField): break else: raise TypeError( "%s isn't ListField or GenericListField type." % name) else: if operator == '$unset': post_deal(operator, current_attr, last_name, value) else: post_deal(operator, current_attr, name_without_dollar, value) result = self.__check_value( current_attr, name_without_dollar, value['value']) if value.has_key('each'): if value['each']: document[operator][original_name]['$each'] = result else: document[operator][original_name] = result[0] else: document[operator][original_name] = result
def deal_with_operator(operator): for name, value in document[operator].items(): value = pre_deal(operator, value) original_name = name name_list = check_key_in_operator_fields(name) name_without_dollar = '.'.join( [name for name in name_list if name != '$']) fields_dict = self.document_cls.fields_dict() if name_list[0] not in fields_dict: raise UndefinedFieldError(field=name_list[0]) current_attr = fields_dict[name_list[0]] if operator == '$unset': last_name = name_list.pop() if not name_list: fields_dict = self.document_cls.fields_dict() if name in fields_dict and fields_dict[name].required: raise FieldDeleteError(field=name) for index, name in enumerate(name_list): if name == '$' or name.isdigit(): if index != len(name_list) - 1: next_name = name_list[index + 1] if next_name.isdigit(): if isinstance(current_attr, ListField): current_attr = current_attr.field elif isinstance(current_attr, GenericListField): break else: raise TypeError( "item in %s should be GenericListField " "or ListField type." % name) else: if isinstance(current_attr.field, DictField): current_attr = current_attr.field elif isinstance(current_attr.field, GenericDictField): break else: raise TypeError( "item in %s should be GenericDictField " "or DictField type." % name) else: if operator == '$unset': post_deal(operator, current_attr, last_name, value) else: post_deal(operator, current_attr, name_without_dollar, value) result = self.__check_value( current_attr, name_without_dollar, value['value']) if value.has_key('each'): if value['each']: document[operator][original_name][ '$each'] = result else: document[operator][ original_name] = result[0] else: document[operator][original_name] = result else: if index != len(name_list) - 1: next_name = name_list[index + 1] if util.legal_variable_name(next_name): if isinstance(current_attr, DictField): current_attr = current_attr.document.fields_dict( )[next_name] elif isinstance(current_attr, GenericDictField): break else: raise TypeError( "'%s' isn't DictField or GenericDictField type." % name) else: if isinstance(current_attr, ListField): current_attr = current_attr.field elif isinstance(current_attr, GenericListField): break else: raise TypeError( "%s isn't ListField or GenericListField type." % name) else: if operator == '$unset': post_deal(operator, current_attr, last_name, value) else: post_deal(operator, current_attr, name_without_dollar, value) result = self.__check_value( current_attr, name_without_dollar, value['value']) if value.has_key('each'): if value['each']: document[operator][original_name][ '$each'] = result else: document[operator][ original_name] = result[0] else: document[operator][original_name] = result