def registerValidation(mapped, exclude=None): ''' Register to mapped class all the validations that can be performed based on the SQL alchemy mapping. @param mapped: class The mapped model class. @param exclude: list[string]|tuple(string) A list of column names to be excluded from automatic validation. @return: Property The property id of the model. ''' assert isclass(mapped), 'Invalid class %s' % mapped mapper, typeModel = mappingFor(mapped), typeFor(mapped) assert isinstance(mapper, Mapper), 'Invalid mapped class %s' % mapped assert isinstance(typeModel, TypeModel), 'Invalid model class %s' % mapped assert not exclude or isinstance(exclude, (list, tuple)), 'Invalid exclude %s' % exclude model = typeModel.container assert isinstance(model, Model) properties = set(model.properties) for cp in mapper.iterate_properties: if not isinstance(cp, ColumnProperty): continue assert isinstance(cp, ColumnProperty) if cp.key: prop = cp.key try: properties.remove(prop) except KeyError: continue if not (exclude and prop in exclude): propRef = getattr(mapped, prop) column = getattr(mapper.c, cp.key, None) assert isinstance(column, Column), 'Invalid column %s' % column if __debug__: propType = typeFor(propRef) assert isinstance(propType, TypeModelProperty), 'Invalid property %s with type %s' % (prop, propType) if column.primary_key and column.autoincrement: if prop != model.propertyId: raise MappingError('The primary key is expected to be %s, but got SQL primary key for %s' % (model.propertyId, prop)) validateAutoId(propRef) elif not column.nullable: validateRequired(propRef) if isinstance(column.type, String) and column.type.length: validateMaxLength(propRef, column.type.length) if column.unique: validateProperty(propRef, partial(onPropertyUnique, mapped)) if column.foreign_keys: for fk in column.foreign_keys: assert isinstance(fk, ForeignKey) try: fkcol = fk.column except AttributeError: raise MappingError('Invalid foreign column for %s, maybe you are not using the meta class' % prop) validateProperty(propRef, partial(onPropertyForeignKey, mapped, fkcol), index=INDEX_PROP_FK) for prop in properties: if not (exclude and prop in exclude): validateManaged(getattr(mapped, prop))
def testValidation(self): Entity._ally_listeners = {} validateAutoId(Entity.Id) validateRequired(Entity.Required) validateMaxLength(Entity.WithLength, 5) validateManaged(Entity.Managed) dummyService = DummyServiceEntity() proxySrvNonValid = proxyWrapFor(dummyService) proxySrv = proxyWrapFor(dummyService) bindValidations(proxySrv) assert isinstance(proxySrv, IServiceEntity) e = Entity() self.assertRaisesRegex(InputError, "(Entity.Required='Expected a value')", proxySrv.insert, e) self.assertEqual(proxySrvNonValid.insert(e), 'inserted') self.assertRaisesRegex(InputError, "(Entity.Id='Expected a value')", proxySrv.update, e) self.assertEqual(proxySrvNonValid.update(e), 'updated') e.Id = 'custom id' self.assertRaisesRegex(InputError, "(Entity.Id='No value expected')", proxySrv.insert, e) self.assertTrue(proxySrv.update(e) == 'updated') e = Entity() e.Required = 'Provided a value' self.assertTrue(proxySrv.insert(e) == 'inserted') e.Id = 'id' self.assertTrue(proxySrv.update(e) == 'updated') e = Entity() e.Required = 'required' e.WithLength = 'This is a longer text then 5' self.assertRaisesRegex(InputError, "(Entity.WithLength='Maximum length allowed is 5)", proxySrv.insert, e) e.WithLength = 'hello' self.assertTrue(proxySrv.insert(e) == 'inserted') e.WithLength = 'This is a longer text then 5' e.Id = 'id' self.assertRaisesRegex(InputError, "(Entity.WithLength='Maximum length allowed is 5)", proxySrv.update, e) e.WithLength = 'hello' self.assertTrue(proxySrv.update(e) == 'updated') e = Entity() e.Required = 'required' e.Managed = 'should not have value' self.assertRaisesRegex(InputError, "(Entity.Managed='No value expected')", proxySrv.insert, e) e.Id = 'id' self.assertRaisesRegex(InputError, "(Entity.Managed='No value expected')", proxySrv.update, e) self.assertRaises(AttributeError, getattr, proxySrv, '_hidden')
def registerValidation(mapped, exclude=None): ''' Register to mapped class all the validations that can be performed based on the SQL alchemy mapping. @param mapped: class The mapped model class. @param exclude: list[string]|tuple(string) A list of column names to be excluded from automatic validation. @return: Property The property id of the model. ''' assert isclass(mapped), 'Invalid class %s' % mapped mapper, typeModel = mappingFor(mapped), typeFor(mapped) assert isinstance(mapper, Mapper), 'Invalid mapped class %s' % mapped assert isinstance(typeModel, TypeModel), 'Invalid model class %s' % mapped assert not exclude or isinstance( exclude, (list, tuple)), 'Invalid exclude %s' % exclude model = typeModel.container assert isinstance(model, Model) properties = set(model.properties) for cp in mapper.iterate_properties: if not isinstance(cp, ColumnProperty): continue assert isinstance(cp, ColumnProperty) if cp.key: prop = cp.key try: properties.remove(prop) except KeyError: continue if not (exclude and prop in exclude): propRef = getattr(mapped, prop) column = getattr(mapper.c, cp.key, None) assert isinstance(column, Column), 'Invalid column %s' % column if __debug__: propType = typeFor(propRef) assert isinstance( propType, TypeModelProperty ), 'Invalid property %s with type %s' % (prop, propType) if column.primary_key and column.autoincrement: if prop != model.propertyId: raise MappingError( 'The primary key is expected to be %s, but got SQL primary key for %s' % (model.propertyId, prop)) validateAutoId(propRef) elif not column.nullable: validateRequired(propRef) if isinstance(column.type, String) and column.type.length: validateMaxLength(propRef, column.type.length) if column.unique: validateProperty(propRef, partial(onPropertyUnique, mapped)) if column.foreign_keys: for fk in column.foreign_keys: assert isinstance(fk, ForeignKey) try: fkcol = fk.column except AttributeError: raise MappingError( 'Invalid foreign column for %s, maybe you are not using the meta class' % prop) validateProperty(propRef, partial(onPropertyForeignKey, mapped, fkcol), index=INDEX_PROP_FK) for prop in properties: if not (exclude and prop in exclude): validateManaged(getattr(mapped, prop))