Пример #1
0
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))
Пример #2
0
def isCompatible(theProperty, withProperty):
    '''
    Checks if the provided property type is compatible with the provided type.
    
    @param theProperty: TypeProperty container
        The property type to check if compatible with the type.
    @param withProperty: TypeProperty container
        The type to check.
    @return: boolean
        True if the property type is compatible with the provided type.
    '''
    typ, wtyp = typeFor(theProperty), typeFor(withProperty)
    if not isinstance(typ, TypeProperty): return False
    assert isinstance(typ, TypeProperty)
    if not isinstance(typ.parent, TypeContainer): return False
    assert isinstance(typ.parent, TypeContainer)
    if not isinstance(wtyp, TypeProperty): return False
    assert isinstance(wtyp, TypeProperty)
    if not isinstance(wtyp.parent, TypeContainer): return False
    assert isinstance(wtyp.parent, TypeContainer)
    if typ.name != wtyp.name: return False
    if typ.type != wtyp.type: return False
    if not issubclass(wtyp.parent.clazz, typ.parent.clazz): return False
    
    return True
Пример #3
0
def isCompatible(theProperty, withProperty):
    '''
    Checks if the provided property type is compatible with the provided type.
    
    @param theProperty: TypeProperty container
        The property type to check if compatible with the type.
    @param withProperty: TypeProperty container
        The type to check.
    @return: boolean
        True if the property type is compatible with the provided type.
    '''
    typ, wtyp = typeFor(theProperty), typeFor(withProperty)
    if not isinstance(typ, TypeProperty): return False
    assert isinstance(typ, TypeProperty)
    if not isinstance(typ.parent, TypeContainer): return False
    assert isinstance(typ.parent, TypeContainer)
    if not isinstance(wtyp, TypeProperty): return False
    assert isinstance(wtyp, TypeProperty)
    if not isinstance(wtyp.parent, TypeContainer): return False
    assert isinstance(wtyp.parent, TypeContainer)
    if typ.name != wtyp.name: return False
    if typ.type != wtyp.type: return False
    if not issubclass(wtyp.parent.clazz, typ.parent.clazz): return False

    return True
Пример #4
0
    def add(self, forRef, theRef):
        '''
        Adds 'theRef' reference as an alternate 'forRef' reference.
        
        @param forRef: tuple(class, string)
            The call reference for which the alternate is specified.
        @param theRef: tuple(class, string)
            The call reference which is an alternative the for reference.
        @return: self
            This instance for chaining purposes.
        '''
        assert isinstance(forRef, tuple), 'Invalid for reference %s' % forRef
        assert isinstance(theRef, tuple), 'Invalid the reference %s' % theRef
        clazz, forName = forRef
        forService = typeFor(clazz)
        assert isinstance(forService,
                          TypeService), 'Invalid service class %s' % clazz
        assert isinstance(forService.service, Service)
        assert forName in forService.service.calls, 'Invalid service call name %s' % forName

        clazz, theName = theRef
        theService = typeFor(clazz)
        assert isinstance(theService,
                          TypeService), 'Invalid service class %s' % clazz
        assert isinstance(theService.service, Service)
        assert theName in theService.service.calls, 'Invalid service call name %s' % theName

        key = (forService, forService.service.calls[forName])
        alternates = self._alternates.get(key)
        if alternates is None: alternates = self._alternates[key] = set()
        alternates.add((theService, theService.service.calls[theName]))

        return self
Пример #5
0
    def processWithRepository(self, alternatesRepository, invoker, invokerAlt):
        '''
        Process the invoker and alternate invoker against the alternates repository.
        
        @return: boolean
            True if the invoker and alternate invoker are configured in the repository.
        '''
        assert isinstance(
            alternatesRepository,
            dict), 'Invalid alternates repository %s' % alternatesRepository
        if invoker == invokerAlt:
            return True  # If the invoker is the same with the alternate it is valid by default

        invokerCall, invokerCallAlt = invokerCallOf(invoker), invokerCallOf(
            invokerAlt)
        if not invoker or not invokerCallAlt:
            return False  # If there are no invoker call then we cannot add them

        assert isinstance(invokerCall, InvokerCall)
        assert isinstance(invokerCallAlt, InvokerCall)

        alternates = alternatesRepository.get(
            (typeFor(invokerCallAlt.implementation), invokerCallAlt.call))
        if alternates is None:
            return False  # There is no alternate repository configuration for the invoker

        try:
            alternates.remove(
                (typeFor(invokerCall.implementation), invokerCall.call))
        except KeyError:
            return False  # Not found in the repository alternate

        return True
Пример #6
0
    def __init__(self, Entity, QEntity=None):
        '''
        Construct the entity support for the provided model class and query class.
        
        @param Entity: class
            The mapped entity model class.
        @param QEntity: class|None
            The query mapped class if there is one.
        '''
        assert isclass(Entity), 'Invalid class %s' % Entity
        assert issubclass(Entity, api.Entity), 'Invalid entity class %s' % Entity
        assert isinstance(Entity, MappedSupport), 'Invalid mapped class %s' % Entity
        self.modelType = typeFor(Entity)
        assert isinstance(self.modelType, TypeModel), 'Invalid model class %s' % Entity

        self.model = self.modelType.container
        self.Entity = Entity

        if QEntity is not None:
            assert isclass(QEntity), 'Invalid class %s' % QEntity
            assert issubclass(QEntity, api.QEntity), 'Invalid query entity class %s' % QEntity
            self.queryType = typeFor(QEntity)
            assert isinstance(self.queryType, TypeQuery), 'Invalid query class %s' % QEntity
            self.query = self.queryType.query
        else:
            self.query = self.queryType = None
        self.QEntity = QEntity
Пример #7
0
    def testSuccesModel(self):
        a = APIModel()

        modelType = typeFor(APIModel)
        self.assertTrue(isinstance(modelType, TypeModel))

        self.assertTrue(len(modelType.properties) == 5)
        self.assertTrue(APIModel.X not in a)
        self.assertTrue(a.X == None)
        a.X = None
        self.assertTrue(APIModel.X in a)
        self.assertTrue(a.X == None)
        self.assertTrue(isinstance(APIModel.X, Reference))
        a.X = 100
        self.assertTrue(a.X == 100)
        a.X = 101.2
        self.assertTrue(a.X == 101.2)

        self.assertTrue(APIModel.Y not in a)
        a.Y = 'heloo'
        self.assertTrue(APIModel.Y in a)
        self.assertTrue(a.Y == 'heloo')
        self.assertTrue(typeFor(APIModel.Y).type.isOf(str))
        del a.Y
        self.assertTrue(a.Y == None)

        self.assertTrue(typeFor(APIModel.Entity.Id).type.isOf(str))
        a.Entity = '121'
        self.assertTrue(APIModel.Entity in a)
        self.assertTrue(isinstance(a.Entity, str))
        self.assertTrue(a.Entity == '121')
        del a.Entity
        self.assertTrue(a.Entity == None)
Пример #8
0
    def testSuccesModel(self):
        a = APIModel()

        modelType = typeFor(APIModel)
        self.assertTrue(isinstance(modelType, TypeModel))

        self.assertTrue(len(modelType.properties) == 5)
        self.assertTrue(APIModel.X not in a)
        self.assertTrue(a.X == None)
        a.X = None
        self.assertTrue(APIModel.X in a)
        self.assertTrue(a.X == None)
        self.assertTrue(isinstance(APIModel.X, Reference))
        a.X = 100
        self.assertTrue(a.X == 100)
        a.X = 101.2
        self.assertTrue(a.X == 101.2)

        self.assertTrue(APIModel.Y not in a)
        a.Y = 'heloo'
        self.assertTrue(APIModel.Y in a)
        self.assertTrue(a.Y == 'heloo')
        self.assertTrue(typeFor(APIModel.Y).type.isOf(str))
        del a.Y
        self.assertTrue(a.Y == None)

        self.assertTrue(typeFor(APIModel.Entity.Id).type.isOf(str))
        a.Entity = '121'
        self.assertTrue(APIModel.Entity in a)
        self.assertTrue(isinstance(a.Entity, str))
        self.assertTrue(a.Entity == '121')
        del a.Entity
        self.assertTrue(a.Entity == None)
Пример #9
0
def equalContainer(ainstance, oinstance, exclude=()):
    '''
    Checks if the values for the provided instances are equal, this means that all properties except the ones in exclude
    need to be equal.
    
    @param ainstance: container object
        A container instance to check.
    @param oinstance: container object
        The other instance to check.
    @param exclude: list[string]|tuple(string)|set(string)
        A list of properties names to exclude from equal check.
    @return: boolean
        True if the instances are equal, False otherwise.
    '''
    assert ainstance is not None and oinstance is not None, 'Invalid instances %s, %s' % (ainstance, oinstance)
    atype, otype = typeFor(ainstance), typeFor(oinstance)
    assert isinstance(atype, TypeContainer), 'Invalid container %s' % ainstance
    assert isinstance(otype, TypeContainer), 'Invalid container %s' % oinstance
    
    if atype != otype:
        properties = set(atype.properties)
        properties.symmetric_difference_update(otype.properties)
        properties.difference_update(exclude)
        if properties: return False  # It means that they are properties that are not accounted for in one of the containers.
        
    for name in atype.properties:
        if name in exclude: continue
        if getattr(ainstance, name) != getattr(oinstance, name): return False
    return True
Пример #10
0
 def add(self, forRef, theRef):
     '''
     Adds 'theRef' reference as an alternate 'forRef' reference.
     
     @param forRef: tuple(class, string)
         The call reference for which the alternate is specified.
     @param theRef: tuple(class, string)
         The call reference which is an alternative the for reference.
     @return: self
         This instance for chaining purposes.
     '''
     assert isinstance(forRef, tuple), 'Invalid for reference %s' % forRef
     assert isinstance(theRef, tuple), 'Invalid the reference %s' % theRef
     clazz, forName = forRef
     forService = typeFor(clazz)
     assert isinstance(forService, TypeService), 'Invalid service class %s' % clazz
     assert isinstance(forService.service, Service)
     assert forName in forService.service.calls, 'Invalid service call name %s' % forName
     
     clazz, theName = theRef
     theService = typeFor(clazz)
     assert isinstance(theService, TypeService), 'Invalid service class %s' % clazz
     assert isinstance(theService.service, Service)
     assert theName in theService.service.calls, 'Invalid service call name %s' % theName
     
     key = (forService, forService.service.calls[forName])
     alternates = self._alternates.get(key)
     if alternates is None: alternates = self._alternates[key] = set()
     alternates.add((theService, theService.service.calls[theName]))
     
     return self
Пример #11
0
    def processHintReplace(self, invoker, prevInvoker):
        """
        Processes the replace for hint for the invokers.
        
        @param invoker: Invoker
            The invoker to be processed.
        @param prevInvoker: Invoker|None
            The previous invoker found on the node if is the case.
        @return: Invoker
            The invoker to be used.
        """
        assert isinstance(invoker, Invoker), "Invalid invoker %s" % invoker
        if prevInvoker:
            replace = invoker.hints.get(self.hintCallReplaceFor)
            if replace is None:
                if isinstance(prevInvoker, Invoker):
                    assert isinstance(prevInvoker, Invoker)
                    replace = prevInvoker.hints.get(self.hintCallReplaceFor)
                if replace is None:
                    raise AssembleError(
                        "Invoker %s conflicts with invoker %s and none of them has a replace specified"
                        % (invoker, prevInvoker)
                    )
                prevInvoker, invoker = invoker, prevInvoker
            typ = typeFor(replace)
            assert isinstance(typ, TypeService), (
                "Invalid replace for reference %s, cannot extract a service from it, provide a service API" % replace
            )

            if typeFor(prevInvoker.implementation) != typ:
                raise AssembleError(
                    "The current invoker %s does not belong to the targeted replaced service %s" % (prevInvoker, typ)
                )

        return invoker
Пример #12
0
    def testSuccesSimpleMapping(self):
        self.assertTrue(typeFor(UserMapped.Id).isOf(int))
        self.assertTrue(typeFor(UserMapped.Name).isOf(str))

        session = self.sessionCreate()
        user = UserMapped()
        self.assertTrue(UserMapped.Id not in user)
        self.assertTrue(UserMapped.Name not in user)

        user.Name = 'Hello world'
        self.assertTrue(UserMapped.Name in user)
        self.assertTrue(UserMapped.Id not in user)

        session.add(user)
        session.flush((user,))
        self.assertTrue(UserMapped.Id in user)

        session.commit()
        session.close()

        session = self.sessionCreate()
        users = session.query(UserMapped).filter(UserMapped.Name == 'Hello world').all()
        self.assertEqual(len(users), 1)
        self.assertTrue(UserMapped.Id in users[0])
        self.assertTrue(UserMapped.Name in users[0])
        self.assertEqual(users[0].Name, 'Hello world')
        self.assertEqual(users[0].Id, 1)
        session.close()
Пример #13
0
    def __init__(self, Mapped, QEntity=None, **mapping):
        '''
        Construct the entity support for the provided model class and query class.
        
        @param Mapped: class
            The mapped entity model class.
        @param QEntity: class|None
            The query mapped class if there is one.
        @param mapping: key arguments of columns
            The column mappings provided for criteria name in case they are needed, this is only used if a QEntity is
            provided.
        '''
        assert isclass(Mapped), 'Invalid class %s' % Mapped
        assert isinstance(Mapped, MappedSupport), 'Invalid mapped class %s' % Mapped
        model = typeFor(Mapped)
        assert isinstance(model, TypeModel), 'Invalid model class %s' % Mapped
        assert isinstance(model.propertyId, TypeProperty), 'Invalid model property id %s' % model.propertyId
        
        self.Entity = model.clazz
        self.Mapped = Mapped
        self.MappedId = modelId(Mapped)

        if QEntity is not None:
            assert isclass(QEntity), 'Invalid class %s' % QEntity
            assert isinstance(typeFor(QEntity), TypeQuery), 'Invalid query entity class %s' % QEntity
            if __debug__:
                for name in mapping:
                    assert name in typeFor(QEntity).properties, 'Invalid criteria name \'%s\' for %s' % (name, QEntity)
            self._mapping = mapping
        else: assert not mapping, 'Illegal mappings %s with no QEntity provided' % mapping
        self.QEntity = QEntity
Пример #14
0
def equalContainer(ainstance, oinstance, exclude=()):
    '''
    Checks if the values for the provided instances are equal, this means that all properties except the ones in exclude
    need to be equal.
    
    @param ainstance: container object
        A container instance to check.
    @param oinstance: container object
        The other instance to check.
    @param exclude: list[string]|tuple(string)|set(string)
        A list of properties names to exclude from equal check.
    @return: boolean
        True if the instances are equal, False otherwise.
    '''
    assert ainstance is not None and oinstance is not None, 'Invalid instances %s, %s' % (
        ainstance, oinstance)
    atype, otype = typeFor(ainstance), typeFor(oinstance)
    assert isinstance(atype, TypeContainer), 'Invalid container %s' % ainstance
    assert isinstance(otype, TypeContainer), 'Invalid container %s' % oinstance

    if atype != otype:
        properties = set(atype.properties)
        properties.symmetric_difference_update(otype.properties)
        properties.difference_update(exclude)
        if properties:
            return False  # It means that they are properties that are not accounted for in one of the containers.

    for name in atype.properties:
        if name in exclude: continue
        if getattr(ainstance, name) != getattr(oinstance, name): return False
    return True
Пример #15
0
    def __init__(self, Entity, QEntity=None):
        '''
        Construct the entity support for the provided model class and query class.
        
        @param Entity: class
            The mapped entity model class.
        @param QEntity: class|None
            The query mapped class if there is one.
        '''
        assert isclass(Entity), 'Invalid class %s' % Entity
        assert issubclass(Entity,
                          api.Entity), 'Invalid entity class %s' % Entity
        assert isinstance(Entity,
                          MappedSupport), 'Invalid mapped class %s' % Entity
        self.modelType = typeFor(Entity)
        assert isinstance(self.modelType,
                          TypeModel), 'Invalid model class %s' % Entity

        self.model = self.modelType.container
        self.Entity = Entity

        if QEntity is not None:
            assert isclass(QEntity), 'Invalid class %s' % QEntity
            assert issubclass(
                QEntity,
                api.QEntity), 'Invalid query entity class %s' % QEntity
            self.queryType = typeFor(QEntity)
            assert isinstance(self.queryType,
                              TypeQuery), 'Invalid query class %s' % QEntity
            self.query = self.queryType.query
        else:
            self.query = self.queryType = None
        self.QEntity = QEntity
Пример #16
0
    def processHintReplace(self, invoker, prevInvoker):
        '''
        Processes the replace for hint for the invokers.
        
        @param invoker: Invoker
            The invoker to be processed.
        @param prevInvoker: Invoker|None
            The previous invoker found on the node if is the case.
        @return: Invoker
            The invoker to be used.
        '''
        assert isinstance(invoker, Invoker), 'Invalid invoker %s' % invoker
        if prevInvoker:
            replace = invoker.hints.get(self.hintCallReplaceFor)
            if replace is None:
                if isinstance(prevInvoker, Invoker):
                    assert isinstance(prevInvoker, Invoker)
                    replace = prevInvoker.hints.get(self.hintCallReplaceFor)
                if replace is None:
                    raise AssembleError(
                        'Invoker %s conflicts with invoker %s and none of them has a replace specified'
                        % (invoker, prevInvoker))
                prevInvoker, invoker = invoker, prevInvoker
            typ = typeFor(replace)
            assert isinstance(typ, TypeService), \
            'Invalid replace for reference %s, cannot extract a service from it, provide a service API' % replace

            if typeFor(prevInvoker.implementation) != typ:
                raise AssembleError(
                    'The current invoker %s does not belong to the targeted replaced service %s'
                    % (prevInvoker, typ))

        return invoker
Пример #17
0
 def __init__(self):
     assert isinstance(self.resourcesRoot,
                       Node), 'Invalid root node %s' % self.resourcesRoot
     node = NodePath(self.resourcesRoot, True, 'MemoryStatus')
     node.get = InvokerFunction(GET, self.present, typeFor(Non), [
         Input('limit', typeFor(Integer), True, None),
         Input('include', typeFor(String), True, None),
         Input('exclude', typeFor(String), True, None),
     ], {})
Пример #18
0
 def __init__(self):
     '''
     Construct the item service.
     '''
     self.Entity = ItemMapped
     self.QEntity = QItem
     self.modelType = typeFor(self.Entity)
     self.model = self.modelType.container
     self.queryType = typeFor(QItem)
Пример #19
0
 def __init__(self):
     assert isinstance(self.resourcesRoot, Node), 'Invalid root node %s' % self.resourcesRoot
     node = NodePath(self.resourcesRoot, True, 'MemoryStatus')
     node.get = InvokerFunction(GET, self.present, typeFor(Non),
                                [
                                 Input('limit', typeFor(Integer), True, None),
                                 Input('include', typeFor(String), True, None),
                                 Input('exclude', typeFor(String), True, None),
                                 ], {})
Пример #20
0
 def __init__(self):
     '''
     Construct the item service.
     '''
     self.Entity = ItemMapped
     self.QEntity = QItem
     self.modelType = typeFor(self.Entity)
     self.model = self.modelType.container
     self.queryType = typeFor(QItem)
Пример #21
0
def signature(obj):
    '''
    Provides the signature for the provided type.
    
    @param obj: Type or container for type container
        The type to provide the signature for.
    @return: string
        The signature.
    '''
    ftype = typeFor(obj)
    assert isinstance(ftype, Type), 'Invalid type %s' % ftype
    if ftype in _signature_cache: return _signature_cache[ftype]
    
    names, ctype, bname = [], ftype, '%s'
    
    if isinstance(ctype, Iter):
        assert isinstance(ctype, Iter)
        bname = '%s[%%s]' % ctype.__class__.__name__
        ctype = ctype.itemType
        
    if isinstance(ctype, (TypeProperty, TypeContainer)):
        isProperty, types = isinstance(ctype, TypeProperty), [ctype]
        while types:
            ctype = types.pop()
            if isProperty:
                assert isinstance(ctype, TypeProperty), 'Invalid property type %s' % ctype
                mtype = ctype.parent
                assert isinstance(mtype, TypeContainer), 'Invalid parent %s' % mtype
                names.append(bname % ('%s.%s.%s' % (mtype.clazz.__module__, mtype.clazz.__name__, ctype.name)))
                bases = ctype.parent.clazz.__bases__
            else:
                assert isinstance(ctype, TypeContainer), 'Invalid container type %s' % ctype
                names.append(bname % ('%s.%s' % (ctype.clazz.__module__, ctype.clazz.__name__)))
                bases = ctype.clazz.__bases__
                
            inherited = []
            for base in bases:
                mtype = typeFor(base)
                if not isinstance(mtype, TypeContainer): continue
                if isProperty:
                    assert isinstance(mtype, TypeContainer)
                    ptype = mtype.properties.get(ctype.name)
                    if not ptype: continue
                    assert isinstance(ptype, TypeProperty), 'Invalid property type %s' % ptype
                    if ctype.type == ptype.type: inherited.append(ptype)
                else: inherited.append(mtype)
                
            if inherited:
                inherited.reverse()
                types.extend(inherited)
                
    else: names.append(bname % ctype)
    
    signature = _signature_cache[ftype] = ''.join(('{0:0>8x}'.format(crc32(name.encode()))).upper() for name in names)
    return signature
Пример #22
0
    def testSuccesBoolean(self):
        bt = typeFor(Boolean)

        self.assertTrue(isinstance(bt, Type))
        self.assertTrue(bt.isOf(bool))
        self.assertTrue(bt.isValid(True))

        bt = typeFor(bool)

        self.assertTrue(bt.isValid(False))
        self.assertTrue(bt.isValid(True))
Пример #23
0
    def testSuccesBoolean(self):
        bt = typeFor(Boolean)

        self.assertTrue(isinstance(bt, Type))
        self.assertTrue(bt.isOf(bool))
        self.assertTrue(bt.isValid(True))

        bt = typeFor(bool)

        self.assertTrue(bt.isValid(False))
        self.assertTrue(bt.isValid(True))
Пример #24
0
    def __init__(self, name, bases, namespace):
        assert isinstance(namespace, dict), 'Invalid namespace %s' % namespace

        mapped, models = [], []
        for cls in bases:
            typ = typeFor(cls)
            if isinstance(typ, TypeModelMapped): mapped.append(cls)
            elif isinstance(typ, TypeModel): models.append(cls)

        if not mapped and not models:
            assert log.debug(
                'Cannot find any API model class for \'%s\', no merging required',
                name) or True
            DeclarativeMeta.__init__(self, name, bases, namespace)
            return

        if len(mapped) > 1:
            raise MappingError(
                'Cannot inherit more then one mapped class, got %s' % models)

        if len(models) > 1:
            raise MappingError(
                'Cannot merge with more then one API model class, got %s' %
                models)

        if models: typeModel = typeFor(models[0])
        else: typeModel = None
        if mapped:
            if typeModel is None: typeModel = typeFor(mapped[0]).base
        assert isinstance(typeModel, TypeModel)
        typeModel = TypeModelMapped(self, typeModel)

        self._ally_reference = {
            prop: Reference(TypeModelProperty(typeModel, prop, propType))
            for prop, propType in typeModel.container.properties.items()
        }
        self._ally_listeners = {}  # Provides the BindableSupport
        self._ally_type = typeModel  # Provides the TypeSupport

        DeclarativeMeta.__init__(self, name, bases, namespace)

        # TODO: see if required: self.__clause_element__ = lambda: self.__table__

        for prop in typeModel.container.properties:
            if typeFor(getattr(self, prop)) != typeFor(
                    self._ally_reference[prop]):
                value, _class = getAttrAndClass(self, prop)
                setattr(self, prop, value)

        try:
            mappings = self.metadata._ally_mappers
        except AttributeError:
            mappings = self.metadata._ally_mappers = deque()
        mappings.append(self)
Пример #25
0
    def testSuccesInt(self):
        it = typeFor(Integer)

        self.assertTrue(isinstance(it, Type))
        self.assertTrue(it.isOf(int))
        self.assertTrue(it.isValid(100))

        it = typeFor(int)

        self.assertTrue(it.isValid(-12))
        self.assertTrue(it.isValid(0))
Пример #26
0
    def testSuccesStr(self):
        st = typeFor(String)

        self.assertTrue(isinstance(st, Type))
        self.assertTrue(st.isOf(str))
        self.assertTrue(st.isValid('ugu'))

        st = typeFor(str)

        self.assertTrue(st.isValid("heloo world"))
        self.assertTrue(st.isValid('Moi'))
Пример #27
0
    def testSuccesInt(self):
        it = typeFor(Integer)

        self.assertTrue(isinstance(it, Type))
        self.assertTrue(it.isOf(int))
        self.assertTrue(it.isValid(100))

        it = typeFor(int)

        self.assertTrue(it.isValid(-12))
        self.assertTrue(it.isValid(0))
Пример #28
0
    def testSuccesStr(self):
        st = typeFor(String)

        self.assertTrue(isinstance(st, Type))
        self.assertTrue(st.isOf(str))
        self.assertTrue(st.isValid('ugu'))

        st = typeFor(str)

        self.assertTrue(st.isValid("heloo world"))
        self.assertTrue(st.isValid('Moi'))
Пример #29
0
    def __init__(self, name, bases, namespace):
        assert isinstance(namespace, dict), "Invalid namespace %s" % namespace

        mapped, models = [], []
        for cls in bases:
            typ = typeFor(cls)
            if isinstance(typ, TypeModelMapped):
                mapped.append(cls)
            elif isinstance(typ, TypeModel):
                models.append(cls)

        if not mapped and not models:
            assert log.debug("Cannot find any API model class for '%s', no merging required", name) or True
            DeclarativeMeta.__init__(self, name, bases, namespace)
            return

        if len(mapped) > 1:
            raise MappingError("Cannot inherit more then one mapped class, got %s" % models)

        if len(models) > 1:
            raise MappingError("Cannot merge with more then one API model class, got %s" % models)

        if models:
            typeModel = typeFor(models[0])
        else:
            typeModel = None
        if mapped:
            if typeModel is None:
                typeModel = typeFor(mapped[0]).base
        assert isinstance(typeModel, TypeModel)
        typeModel = TypeModelMapped(self, typeModel)

        self._ally_reference = {
            prop: Reference(TypeModelProperty(typeModel, prop, propType))
            for prop, propType in typeModel.container.properties.items()
        }
        self._ally_listeners = {}  # Provides the BindableSupport
        self._ally_type = typeModel  # Provides the TypeSupport

        DeclarativeMeta.__init__(self, name, bases, namespace)

        # TODO: see if required: self.__clause_element__ = lambda: self.__table__

        for prop in typeModel.container.properties:
            if typeFor(getattr(self, prop)) != typeFor(self._ally_reference[prop]):
                value, _class = getAttrAndClass(self, prop)
                setattr(self, prop, value)

        try:
            mappings = self.metadata._ally_mappers
        except AttributeError:
            mappings = self.metadata._ally_mappers = deque()
        mappings.append(self)
Пример #30
0
 def __init__(self):
     '''
     Construct the handler.
     '''
     assert self.maximumLimit is None or isinstance(self.maximumLimit, int), 'Invalid maximum limit %s' % self.maximumLimit
     assert self.defaultLimit is None or isinstance(self.defaultLimit, int), 'Invalid default limit %s' % self.defaultLimit
     assert self.defaultWithTotal is None or isinstance(self.defaultWithTotal, bool), \
     'Invalid default with total %s' % self.defaultWithTotal
     super().__init__(Decoding=Decoding)
     
     self.typeLimit = typeFor(Slice.limit)
     self.typeTotal = typeFor(SliceAndTotal.withTotal)
Пример #31
0
def handle(e, entity):
    '''
    Handles the SQL alchemy exception while inserting or updating.
    '''
    if isinstance(e, IntegrityError):
        raise InputError(
            Ref(_('Cannot persist, failed unique constraints on entity'),
                model=typeFor(entity).container))
    if isinstance(e, OperationalError):
        raise InputError(
            Ref(_('A foreign key is not valid'),
                model=typeFor(entity).container))
    raise e
Пример #32
0
    def testSuccesNumber(self):
        nt = typeFor(Number)

        self.assertTrue(isinstance(nt, Type))
        self.assertTrue(nt.isOf(numbers.Number))
        self.assertTrue(nt.isValid(100))

        nt = typeFor(float)

        self.assertTrue(nt.isValid(100.12))

        nt = typeFor(numbers.Number)

        self.assertTrue(nt.isValid(-1.12))
Пример #33
0
    def testSuccesNumber(self):
        nt = typeFor(Number)

        self.assertTrue(isinstance(nt, Type))
        self.assertTrue(nt.isOf(numbers.Number))
        self.assertTrue(nt.isValid(100))

        nt = typeFor(float)

        self.assertTrue(nt.isValid(100.12))

        nt = typeFor(numbers.Number)

        self.assertTrue(nt.isValid(-1.12))
Пример #34
0
    def testSuccessInheritAndForeignKey(self):
        self.assertTrue(typeFor(UserWithParent.Id).isOf(int))
        self.assertTrue(typeFor(UserWithParent.Name).isOf(str))
        self.assertTrue(typeFor(UserWithParent.Parent).isOf(Parent))

        session = self.sessionCreate()
        user = UserWithParent()
        self.assertTrue(UserWithParent.Id not in user)
        self.assertTrue(UserWithParent.Name not in user)
        self.assertTrue(UserWithParent.Parent not in user)

        user.Name = 'Hello world'
        self.assertTrue(UserWithParent.Name in user)

        user.Parent = 1
        self.assertTrue(UserWithParent.Parent in user)
        self.assertTrue(UserWithParent.Id not in user)

        session.add(user)
        session.flush((user,))
        self.assertTrue(UserWithParent.Id in user)

        session.commit()
        session.close()

        session = self.sessionCreate()
        users = session.query(UserWithParent).filter(UserWithParent.Name == 'Hello world').all()
        self.assertEqual(len(users), 1)
        user = users[0]
        self.assertTrue(UserWithParent.Id in user)
        self.assertTrue(UserWithParent.Name in user)
        self.assertTrue(UserWithParent.Parent in user)
        self.assertEqual(user.Name, 'Hello world')
        self.assertEqual(user.Id, 1)
        self.assertEqual(user.Parent, 1)
        session.close()

        session = self.sessionCreate()
        users = session.query(UserWithParent).filter(UserWithParent.Parent == 1).all()
        self.assertEqual(len(users), 1)
        user = users[0]
        self.assertTrue(UserWithParent.Id in user)
        self.assertTrue(UserWithParent.Name in user)
        self.assertTrue(UserWithParent.Parent in user)
        self.assertEqual(user.Name, 'Hello world')
        self.assertEqual(user.Id, 1)
        self.assertEqual(user.Parent, 1)
        session.close()
Пример #35
0
def updateModel(Mapped, model, **data):
    '''
    Updates the provided model entity using the current session.

    @param Mapped: class
        The mapped class to update the model for, the model type is required to have a property id.
    @param model: object
        The model to be updated.
    @param data: key arguments
        Additional data to place on the updated model.
    @return: object
        The database model that has been updated.
    '''
    assert isclass(Mapped), 'Invalid class %s' % Mapped
    assert isinstance(Mapped, MappedSupport), 'Invalid mapped class %s' % Mapped
    if isinstance(model, Mapped):
        dbModel = model
        openSession().merge(dbModel)
    else:
        typ = typeFor(Mapped)
        assert isinstance(typ, TypeModel), 'Invalid model class %s' % Mapped
        assert typ.isValid(model), 'Invalid model %s for %s' % (model, typ)
        assert isinstance(typ.propertyId, TypeProperty), 'Invalid property id of %s' % typ
        
        dbModel = openSession().query(Mapped).get(getattr(model, typ.propertyId.name))
        if not dbModel: raise IdError(typ.propertyId)
        for name, prop in typ.properties.items():
            if name in data or not isinstance(getattr(Mapped, name), InstrumentedAttribute): continue
            if prop in model: setattr(dbModel, name, getattr(model, name))
            
        for name, value in data.items(): setattr(dbModel, name, value)
    
    openSession().flush((dbModel,))
    return dbModel
Пример #36
0
    def __call__(self, value, normalizer, converter, render, resolve, name=None, **data):
        assert isinstance(normalizer, Normalizer), 'Invalid normalizer %s' % normalizer
        assert isinstance(converter, Converter), 'Invalid converter %s' % converter
        assert isinstance(render, IRender), 'Invalid render %s' % render
        assert isinstance(resolve, IResolve), 'Invalid resolve %s' % resolve

        if self.getter: value = self.getter(value)
        if value is None: return
        assert isinstance(value, Iterable), 'Invalid value %s' % value

        typeValue = typeFor(value)
        if typeValue and isinstance(typeValue, TypeExtension):
            assert isinstance(typeValue, TypeExtension)
            assert isinstance(typeValue.container, Container)
            attrs = {}
            for prop, propType in typeValue.container.properties.items():
                propValue = getattr(value, prop)
                if propValue is not None: attrs[normalizer.normalize(prop)] = converter.asString(propValue, propType)
        else: attrs = None

        data.update(normalizer=normalizer, converter=converter, render=render, resolve=resolve)

        render.collectionStart(normalizer.normalize(name or self.name), attrs)
        resolve.queueBatch(self.exploitItem, (dict(data, value=item) for item in value))
        resolve.queue(self.finalize, render=render)
Пример #37
0
 def allFor(self, method, *services, filter=None):
     '''
     Used for adding to the right the service calls that have the specified method.
     
     @param method: integer
         The method or methods composed by using the | operator to be associated with the right.
     @param service: arguments[service type]
         The services types to be used.
     @param filter: Filter|None
         The filter to be used with the added services, for more details about filter policy.
     @return: self
         The self object for chaining purposes.
     '''
     assert isinstance(method, int), 'Invalid method %s' % method
     assert services, 'At least one service is required'
     
     for service in services:
         typ = typeFor(service)
         assert isinstance(typ, TypeService), 'Invalid service %s' % service
         
         assert isinstance(typ.service, Service)
         for call in typ.service.calls.values():
             assert isinstance(call, Call)
             if call.method & method:
                 structCall = self.structure.obtainCall(typ, call)
                 if filter: structCall.pushFilter(filter)
     return self
Пример #38
0
 def add(self, *references, filter=None):
     '''
     Used for adding to the right the service calls.
     
     @param references: arguments[tuple(class, string)]
         The references of the service call to associate with the right.
     @param filter: Filter|None
         The filter to be used with the added calls, for more details about filter policy.
     @return: self
         The self object for chaining purposes.
     '''
     indexed = iterRef(references)
     assert indexed, 'At least one reference is required'
     for service, names in indexed.items():
         typ = typeFor(service)
         assert isinstance(typ, TypeService), 'Invalid service %s' % service
         assert isinstance(typ.service, Service)
         for name in names:
             if isfunction(name): name = name.__name__
             assert name in typ.service.calls, 'Invalid call name \'%s\' for service %s' % (name, typ)
             call = typ.service.calls[name]
             assert isinstance(call, Call)
             structCall = self.structure.obtainCall(typ, call)
             if filter: structCall.pushFilter(filter)
     return self
Пример #39
0
def callsOf(stack):
    '''
    Provides the call types for the provided stack object.
    
    @param stack: Exception|traceback
        The exception or trace back object to extract the calls from.
    @return: list[TypeCall]
        The calls from the stack.
    '''
    if isinstance(stack, Exception):
        assert isinstance(stack, Exception)
        tb = stack.__traceback__
    else:
        tb = stack
    assert isinstance(tb, TracebackType), 'Invalid trace back %s' % tb

    calls = []
    while tb:
        instance = tb.tb_frame.f_locals.get('self')
        if instance is not None:
            service = typeFor(instance)
            if isinstance(service, TypeService):
                assert isinstance(service, TypeService)
                call = service.calls.get(tb.tb_frame.f_code.co_name)
                if call: calls.append(call)
        tb = tb.tb_next
    return calls
Пример #40
0
 def isOf(self, type):
     '''
     @see: TypeClass.isOf
     '''
     if isclass(type) and (issubclass(type, self.clazz) or issubclass(self.clazz, type)): return True
     if self == typeFor(type): return True
     return False
Пример #41
0
 def populate(self, obj, specifications, support):
     '''
     @see: ISpecifier.populate
     '''
     ext = typeFor(obj)
     if not ext or not isinstance(ext, TypeExtension): return  # Is not an extension object, nothing to do
     assert isinstance(ext, TypeExtension)
     
     if ext not in self.propertiesByType:
         properties = self.propertiesByType[ext] = []
         for name, prop in ext.properties.items():
             assert isinstance(prop, TypeProperty), 'Invalid property %s' % prop
             encoder = createEncoderNamed(self.processing, name, prop)
             if encoder is None: log.error('Cannot encode %s of %s', prop, ext)
             else: properties.append((name, encoder))
     else: properties = self.propertiesByType[ext]
     
     attributes = specifications.get('attributes')
     if attributes is None: attributes = specifications['attributes'] = {}
     render = RenderAttributes(attributes)
     for name, encoder in properties:
         assert isinstance(encoder, ITransfrom), 'Invalid property encoder %s' % encoder
         objValue = getattr(obj, name)
         if objValue is None: continue
         encoder.transform(objValue, render, support)
Пример #42
0
    def process(self, request: Request, **keyargs):
        '''
        @see: HandlerProcessorProceed.process
        
        Transpose the additional arguments into the main arguments.
        '''
        assert isinstance(request, Request), 'Invalid request %s' % request
        if request.invoker is None:
            return  # If there is no invoker it means that no arguments need to be processed
        assert isinstance(request.path,
                          Path), 'Invalid request path %s' % request.path
        assert isinstance(
            request.invoker,
            Invoker), 'Invalid request invoker %s' % request.invoker

        if request.argumentsOfType:
            for inp in request.invoker.inputs:
                assert isinstance(inp, Input), 'Invalid input %s' % inp

                if inp.name in request.arguments: continue

                for argType, value in request.argumentsOfType.items():
                    if typeFor(argType) == inp.type:
                        if inp.name not in request.arguments:
                            request.arguments[inp.name] = value
                        break

        request.arguments.update(request.path.toArguments(request.invoker))
Пример #43
0
def insertModel(Mapped, model, **data):
    '''
    Inserts the provided model entity using the current session.

    @param Mapped: class
        The mapped class to insert the model for.
    @param model: object
        The model to insert.
    @param data: key arguments
        Additional data to place on the inserted model.
    @return: object
        The database model that has been inserted.
    '''
    assert isclass(Mapped), 'Invalid class %s' % Mapped
    assert isinstance(Mapped,
                      MappedSupport), 'Invalid mapped class %s' % Mapped
    if isinstance(model, Mapped): dbModel = model
    else:
        typ, mapper = typeFor(Mapped), mappingFor(Mapped)
        assert isinstance(typ, TypeModel), 'Invalid model class %s' % Mapped
        assert isinstance(mapper, Mapper), 'Invalid mapper %s' % mapper

        dbModel = Mapped()
        for name, prop in typ.properties.items():
            if name in data or not isinstance(getattr(Mapped, name),
                                              InstrumentedAttribute):
                continue
            if prop in model: setattr(dbModel, name, getattr(model, name))

        for name, value in data.items():
            setattr(dbModel, name, value)

    openSession().add(dbModel)
    openSession().flush((dbModel, ))
    return dbModel
Пример #44
0
    def processHintWebName(self, types, hints, isGroup=False):
        """
        Processes the web name hint found on the call and alters the provided types list according to it.
        
        @param types: list[Input|TypeModel|Model|tuple(string,boolean)]
            The list of types to be altered based on the web name hint.
        @param hints: dictionary{string, object}
            The hints to be processed for the types.
        @param isGroup: boolean
            Flag indicating that the web name hint should be considered a group node (True) or an object node (False).
        """
        assert isinstance(types, list), "Invalid types %s" % types
        assert isinstance(hints, dict), "Invalid hints %s" % hints
        assert isinstance(isGroup, bool), "Invalid is group flag %s" % isGroup

        webName = hints.get(self.hintCallWebName)
        if isclass(webName):
            typ = typeFor(webName)
            assert isinstance(typ, TypeModel), "Invalid web name hint class %s" % webName
            types.append(typ.container)
        elif webName:
            assert isinstance(webName, str), "Invalid web name hint %s" % webName
            webName = webName.split("/")
            for k, name in enumerate(webName):
                assert re.match("^[\w]+$", name), 'Invalid name "%s" in web name "%s"' % (name, "/".join(webName))
                types.append((name, False if k <= len(webName) - 1 else isGroup))
        return types
Пример #45
0
def deleteModel(Mapped, identifier):
    '''
    Delete the provided model based on the provided identifier using the current session.

    @param Mapped: class
        The mapped class to update the model for, the model type is required to have a property id.
    @param identifier: object
        The identifier to delete for.
    @return: boolean
        True if any entry was deleted, False otherwise.
    '''
    assert isclass(Mapped), 'Invalid class %s' % Mapped
    assert isinstance(Mapped,
                      MappedSupport), 'Invalid mapped class %s' % Mapped
    typ = typeFor(Mapped)
    assert isinstance(typ, TypeModel), 'Invalid model class %s' % Mapped
    assert isinstance(typ.propertyId,
                      TypeProperty), 'Invalid property id of %s' % typ
    assert typ.propertyId.isValid(
        identifier), 'Invalid identifier %s for %s' % (identifier,
                                                       typ.propertyId)

    try:
        model = openSession().query(Mapped).filter(
            getattr(Mapped, typ.propertyId.name) == identifier).one()
    except NoResultFound:
        return False
    openSession().delete(model)
    return True
Пример #46
0
    def authenticate(self, identifier, attributes, arguments):
        '''
        @see: IAuthenticationSupport.authenticate
        '''
        assert isinstance(identifier, str), 'Invalid identifier %s' % identifier
        assert isinstance(attributes, dict), 'Invalid attributes %s' % attributes
        assert isinstance(arguments, dict), 'Invalid arguments %s' % arguments

        olderThan = self.session().query(current_timestamp()).scalar()
        olderThan -= self.sessionTimeOut
        sql = self.session().query(LoginMapped)
        sql = sql.filter(LoginMapped.Session == identifier)
        sql = sql.filter(LoginMapped.AccessedOn > olderThan)
        try: login = sql.one()
        except NoResultFound: return False
        assert isinstance(login, LoginMapped), 'Invalid login %s' % login
        login.AccessedOn = current_timestamp()
        self.session().flush((login,))
        self.session().expunge(login)
        commitNow()
        # We need to fore the commit because if there is an exception while processing the request we need to make
        # sure that the last access has been updated.

        for authType in arguments:
            assert isinstance(authType, Type), 'Invalid type %s' % authType

            if authType == typeFor(User.Id): arguments[authType] = login.User
            else: raise DevelError('Invalid authenticated type %s' % authType)

        return True
Пример #47
0
    def __call__(self, value, normalizer, converter, render, resolve, name=None, **data):
        assert isinstance(normalizer, Normalizer), 'Invalid normalizer %s' % normalizer
        assert isinstance(converter, Converter), 'Invalid converter %s' % converter
        assert isinstance(render, IRender), 'Invalid render %s' % render
        assert isinstance(resolve, IResolve), 'Invalid resolve %s' % resolve

        if self.getter: value = self.getter(value)
        if value is None: return
        assert isinstance(value, Iterable), 'Invalid value %s' % value

        typeValue = typeFor(value)
        if typeValue and isinstance(typeValue, TypeExtension):
            assert isinstance(typeValue, TypeExtension)
            assert isinstance(typeValue.container, Container)
            attrs = {}
            for prop, propType in typeValue.container.properties.items():
                propValue = getattr(value, prop)
                if propValue is not None: attrs[normalizer.normalize(prop)] = converter.asString(propValue, propType)
        else: attrs = None

        data.update(normalizer=normalizer, converter=converter, render=render, resolve=resolve)

        render.collectionStart(normalizer.normalize(name or self.name), attrs)
        resolve.queueBatch(self.exploitItem, (dict(data, value=item) for item in value))
        resolve.queue(self.finalize, render=render)
Пример #48
0
    def __init__(self):
        '''
        Construct the handler.
        '''
        assert self.maximumLimit is None or isinstance(
            self.maximumLimit,
            int), 'Invalid maximum limit %s' % self.maximumLimit
        assert self.defaultLimit is None or isinstance(
            self.defaultLimit,
            int), 'Invalid default limit %s' % self.defaultLimit
        assert self.defaultWithTotal is None or isinstance(self.defaultWithTotal, bool), \
        'Invalid default with total %s' % self.defaultWithTotal
        super().__init__(Decoding=Decoding)

        self.typeLimit = typeFor(Slice.limit)
        self.typeTotal = typeFor(SliceAndTotal.withTotal)
Пример #49
0
def relationshipModel(mappedId, *spec):
    '''
    Creates a relationship with the model, this should only be used in case the mapped model database id is different from the
    actual model id.
    
    @param mappedId: InstrumentedAttribute
        The mapped model id to create the relation with.
    @param spec: arguments containing
        column: string
            The column name containing the foreign key relation, attention if target is provided then
            also column needs to be provided, if None provided it will create one automatically.
        target: string
            The SQL alchemy relationship target name, if None provided it will create one automatically.
    '''
    assert isinstance(mappedId,
                      InstrumentedAttribute), 'Invalid mapped id %s' % mappedId
    register = callerLocals()
    assert '__module__' in register, 'This function should only be used inside meta class definitions'
    rtype = typeFor(mappedId.class_)
    assert isinstance(rtype, TypeModel), 'Invalid class %s' % mappedId.class_
    assert isinstance(rtype.propertyId,
                      TypeProperty), 'No property id for %s' % rtype
    assert rtype.propertyId.name != mappedId.property.key, 'Same database id with the model id \'%s\' for %s' % mappedId.class_

    column = target = None
    if spec:
        column, *spec = spec
        assert isinstance(column, str), 'Invalid column %s' % column
        if spec:
            target, = spec
            assert isinstance(target,
                              str) and target, 'Invalid target %s' % target

    if target is None:
        target = modifyFirst(rtype.name, False)
        if column is None:
            column = '%sId' % target
            register[column] = Column('fk_%s_id' % toUnderscore(target),
                                      ForeignKey(mappedId, ondelete='CASCADE'),
                                      nullable=False)
        register[target] = relationship(mappedId.class_,
                                        uselist=False,
                                        lazy='joined',
                                        viewonly=True)

    def fget(self):
        rel = getattr(self, target)
        if rel: return getattr(rel, rtype.propertyId.name)

    columnId = columnFor(getattr(mappedId.class_, rtype.propertyId.name))

    def fset(self, value):
        setattr(self, column, select([mappedId], columnId == value))

    validation = validate(Mandatory, Relation)
    return validation(
        hybrid_property(fget,
                        fset,
                        expr=joinedExpr(mappedId.class_,
                                        rtype.propertyId.name)))
Пример #50
0
    def processHintWebName(self, types, hints, isGroup=False):
        '''
        Processes the web name hint found on the call and alters the provided types list according to it.
        
        @param types: list[Input|TypeModel|Model|tuple(string,boolean)]
            The list of types to be altered based on the web name hint.
        @param hints: dictionary{string, object}
            The hints to be processed for the types.
        @param isGroup: boolean
            Flag indicating that the web name hint should be considered a group node (True) or an object node (False).
        '''
        assert isinstance(types, list), 'Invalid types %s' % types
        assert isinstance(hints, dict), 'Invalid hints %s' % hints
        assert isinstance(isGroup, bool), 'Invalid is group flag %s' % isGroup

        webName = hints.get(self.hintCallWebName)
        if isclass(webName):
            typ = typeFor(webName)
            assert isinstance(
                typ, TypeModel), 'Invalid web name hint class %s' % webName
            types.append(typ.container)
        elif webName:
            assert isinstance(webName,
                              str), 'Invalid web name hint %s' % webName
            webName = webName.split('/')
            for k, name in enumerate(webName):
                assert re.match('^[\w]+$',
                                name), 'Invalid name "%s" in web name "%s"' % (
                                    name, '/'.join(webName))
                types.append(
                    (name, False if k <= len(webName) - 1 else isGroup))
        return types
Пример #51
0
 def process(self, chain, register:Register, **keyargs):
     '''
     @see: HandlerProcessor.process
     
     Populate the content flag if required.
     '''
     assert isinstance(register, Register), 'Invalid register %s' % register
     if not register.invokers: return  # No invokers to process.
     
     aborted = []
     for invoker in register.invokers:
         assert isinstance(invoker, InvokerAssembler), 'Invalid invoker %s' % invoker
         if not invoker.inputs: continue
         
         inpContent, toMany = None, False
         for inp in invoker.inputs:
             assert isinstance(inp, Input), 'Invalid input %s' % inp
             if inp.type == self.contentType:
                 if inpContent is not None: toMany = True
                 inpContent = inp
         
         if toMany:
             log.error('Cannot use because there are to many \'%s\' inputs, only a maximum of one is allowed, at:%s',
                       typeFor(Content), invoker.location)
             aborted.append(invoker)
         elif inpContent:
             if invoker.solved is None: invoker.solved = set()
             invoker.solved.add(inpContent)
             invoker.inputContent = inpContent
             
     if aborted: raise Abort(*aborted)
Пример #52
0
    def process(self, chain, register:Register, **keyargs):
        '''
        @see: HandlerProcessor.process
        
        Provides the conflict resolving.
        '''
        assert isinstance(register, Register), 'Invalid register %s' % register

        if Register.hintsCall in register:
            if register.hintsCall is None: register.hintsCall = {}
            register.hintsCall[self.hintName] = self.hintDescription
            
        if not register.nodes: return
        
        reported, aborted = set(), []
        for node in register.nodes:
            assert isinstance(node, Node), 'Invalid node %s' % node
            if not node.conflicts: continue
            assert isinstance(node.conflicts, dict), 'Invalid conflicts %s' % node.conflicts
            
            for invokers in node.conflicts.values():
                assert  isinstance(invokers, list), 'Invalid invokers %s' % invokers
                byService, solving = {}, []
                for invoker in invokers:
                    assert isinstance(invoker, Invoker), 'Invalid invoker %s' % invoker
                    if not invoker.service or not invoker.call: continue
                    if invoker.service in byService: continue
                    replaces = invoker.call.hints.get(self.hintName)
                    if not replaces: continue
                    if not isinstance(replaces, tuple): replaces = (replaces,)
                    
                    byService[invoker.service] = invoker
                    solving.append((invoker, replaces))
                
                if byService:
                    locations = []
                    for invoker, replaces in solving:
                        locations.append(invoker.location)
                        for clazz in replaces:
                            service = typeFor(clazz)
                            if not isinstance(service, TypeService):
                                log.error('Cannot use invoker because the replace hints are invalid, at:%s, '
                                          'it should be:\n%s', invoker.location, self.hintDescription)
                                aborted.append(invoker)
                                break
                            assert isinstance(service, TypeService), 'Invalid service class %s' % clazz
                            byService.pop(service, None)
                    
                    if not byService:
                        if reported.isdisjoint(locations):
                            log.error('Cannot use invokers because the replace hints are circular among them, at:%s',
                                      ''.join(locations))
                            reported.update(locations)
                        aborted.extend(invokers)
                    else:
                        solved = set(byService)
                        for invoker, replaces in solving:
                            if invoker not in solved: aborted.append(invoker)

        if aborted: raise Abort(*aborted)
Пример #53
0
    def populate(self, obj, specifications, support):
        '''
        @see: ISpecifier.populate
        '''
        ext = typeFor(obj)
        if not ext or not isinstance(ext, TypeExtension):
            return  # Is not an extension object, nothing to do
        assert isinstance(ext, TypeExtension)

        if ext not in self.propertiesByType:
            properties = self.propertiesByType[ext] = []
            for name, prop in ext.properties.items():
                assert isinstance(prop,
                                  TypeProperty), 'Invalid property %s' % prop
                encoder = createEncoderNamed(self.processing, name, prop)
                if encoder is None:
                    log.error('Cannot encode %s of %s', prop, ext)
                else:
                    properties.append((name, encoder))
        else:
            properties = self.propertiesByType[ext]

        attributes = specifications.get('attributes')
        if attributes is None: attributes = specifications['attributes'] = {}
        render = RenderAttributes(attributes)
        for name, encoder in properties:
            assert isinstance(
                encoder, ITransfrom), 'Invalid property encoder %s' % encoder
            objValue = getattr(obj, name)
            if objValue is None: continue
            encoder.transform(objValue, render, support)
Пример #54
0
    def process(self,
                chain,
                decoding: Decoding,
                definition: Context = None,
                **keyargs):
        '''
        @see: HandlerProcessor.process
        
        Wrap with explode decoders.
        '''
        assert isinstance(decoding, Decoding), 'Invalid decoding %s' % decoding

        if not decoding.doDecode: return

        if not isinstance(decoding.type, List):
            return  # The type is not a list, just move along.
        assert isinstance(decoding.type, List)

        decoding.doDecode = self.createExplode(decoding.doDecode)

        assert isinstance(definition,
                          Definition), 'Invalid definition %s' % definition
        assert isinstance(definition.types,
                          list), 'Invalid definition %s' % definition.types
        definition.types.append(typeFor(str))
Пример #55
0
    def process(self, chain, register: Register, **keyargs):
        '''
        @see: HandlerProcessor.process
        
        Populate the content flag if required.
        '''
        assert isinstance(register, Register), 'Invalid register %s' % register
        if not register.invokers: return  # No invokers to process.

        aborted = []
        for invoker in register.invokers:
            assert isinstance(invoker,
                              InvokerAssembler), 'Invalid invoker %s' % invoker
            if not invoker.inputs: continue

            inpContent, toMany = None, False
            for inp in invoker.inputs:
                assert isinstance(inp, Input), 'Invalid input %s' % inp
                if inp.type == self.contentType:
                    if inpContent is not None: toMany = True
                    inpContent = inp

            if toMany:
                log.error(
                    'Cannot use because there are to many \'%s\' inputs, only a maximum of one is allowed, at:%s',
                    typeFor(Content), invoker.location)
                aborted.append(invoker)
            elif inpContent:
                if invoker.solved is None: invoker.solved = set()
                invoker.solved.add(inpContent)
                invoker.inputContent = inpContent

        if aborted: raise Abort(*aborted)
Пример #56
0
def findNodesFor(node, typeService, name):
    '''
    Finds all the nodes in the root node for the provided service type and call name.
    
    @param node: Node
        The root node to start the find in.
    @param typeService: TypeService
        The service type to find the paths for.
    @param name: string
        The call name to find the paths for.
    @return: list[Node]
        The nodes of the service type and call name.
    '''
    assert isinstance(node, Node), 'Invalid node %s' % node
    assert isinstance(typeService,
                      TypeService), 'Invalid type service %s' % typeService
    assert isinstance(name, str), 'Invalid call name %s' % name
    assert isinstance(typeService.service, Service)
    call = typeService.service.calls.get(name)
    assert isinstance(
        call,
        Call), 'Invalid call name \'%s\' for service %s' % (name, typeService)

    nodes, attr = [], METHOD_NODE_ATTRIBUTE[call.method]
    for node in iterateNodes(node):
        invoker = getattr(node, attr)
        if not invoker: continue
        invoker = invokerCallOf(invoker)
        if not invoker: continue
        assert isinstance(invoker, InvokerCall)
        assert isinstance(invoker.call, Call)
        if typeService == typeFor(
                invoker.implementation) and invoker.call.name == name:
            nodes.append(node)
    return nodes
Пример #57
0
def onPropertyUnique(mapped, prop, obj, errors):
    '''
    Validation of a sql alchemy unique property.
    
    @param mapped: class
        The mapped model class.
    @param prop: string
        The property name to be checked if unique.
    @param obj: object
        The entity to check for the property value.
    @param errors: list[Ref]
        The list of errors.
    '''
    assert isclass(mapped), 'Invalid class %s' % mapped
    assert isinstance(prop, str), 'Invalid property name %s' % prop
    assert obj is not None, 'None is not a valid object'
    assert isinstance(errors, list), 'Invalid errors list %s' % errors

    propRef = getattr(mapped, prop)
    if propRef in obj:
        try:
            db = openSession().query(mapped).filter(propRef == getattr(obj, prop)).one()
        except NoResultFound:
            return
        propId = typeFor(mapped).container.propertyId
        if getattr(obj, propId) != getattr(db, propId):
            errors.append(Ref(_('Already an entry with this value'), ref=propRef))
            return False