Skip to content
Snippets Groups Projects
ConstraintModel.py 3.2 KiB
Newer Older
Lluis Gifre Renom's avatar
Lluis Gifre Renom committed
import logging, operator
Lluis Gifre Renom's avatar
Lluis Gifre Renom committed
from typing import Dict, List, Tuple, Union
from common.orm.Database import Database
from common.orm.HighLevel import get_or_create_object, update_or_create_object
from common.orm.backend.Tools import key_to_str
Lluis Gifre Renom's avatar
Lluis Gifre Renom committed
from common.orm.fields.ForeignKeyField import ForeignKeyField
from common.orm.fields.IntegerField import IntegerField
from common.orm.fields.PrimaryKeyField import PrimaryKeyField
from common.orm.fields.StringField import StringField
from common.orm.model.Model import Model
Lluis Gifre Renom's avatar
Lluis Gifre Renom committed
from context.proto.context_pb2 import Constraint
from context.service.database.Tools import fast_hasher, remove_dict_key
Lluis Gifre Renom's avatar
Lluis Gifre Renom committed

LOGGER = logging.getLogger(__name__)

Lluis Gifre Renom's avatar
Lluis Gifre Renom committed
class ConstraintsModel(Model): # pylint: disable=abstract-method
Lluis Gifre Renom's avatar
Lluis Gifre Renom committed
    pk = PrimaryKeyField()

    def dump(self) -> List[Dict]:
        db_constraint_pks = self.references(ConstraintModel)
        constraints = [ConstraintModel(self.database, pk).dump(include_position=True) for pk,_ in db_constraint_pks]
        constraints = sorted(constraints, key=operator.itemgetter('position'))
        return [remove_dict_key(constraint, 'position') for constraint in constraints]

Lluis Gifre Renom's avatar
Lluis Gifre Renom committed
class ConstraintModel(Model): # pylint: disable=abstract-method
Lluis Gifre Renom's avatar
Lluis Gifre Renom committed
    pk = PrimaryKeyField()
    constraints_fk = ForeignKeyField(ConstraintsModel)
    position = IntegerField(min_value=0, required=True)
    constraint_type = StringField(required=True, allow_empty=False)
    constraint_value = StringField(required=True, allow_empty=False)

    def dump(self, include_position=True) -> Dict: # pylint: disable=arguments-differ
        result = {
            'constraint_type': self.constraint_type,
            'constraint_value': self.constraint_value,
        }
        if include_position: result['position'] = self.position
        return result
Lluis Gifre Renom's avatar
Lluis Gifre Renom committed

def set_constraint(
    database : Database, db_constraints : ConstraintsModel, grpc_constraint, position : int
    ) -> Tuple[Constraint, bool]:

    str_constraint_key_hash = fast_hasher(grpc_constraint.constraint_type)
    str_constraint_key = key_to_str([db_constraints.pk, str_constraint_key_hash], separator=':')

    result : Tuple[ConstraintModel, bool] = update_or_create_object(database, ConstraintModel, str_constraint_key, {
        'constraints_fk'  : db_constraints,
        'position'        : position,
        'constraint_type' : grpc_constraint.constraint_type,
        'constraint_value': grpc_constraint.constraint_value,
    })
    db_config_rule, updated = result
    return db_config_rule, updated

def set_constraints(
    database : Database, db_parent_pk : str, constraints_name : str, grpc_constraints
    ) -> List[Tuple[Union[ConstraintsModel, ConstraintModel], bool]]:

    str_constraints_key = key_to_str([db_parent_pk, constraints_name], separator=':')
    result : Tuple[ConstraintsModel, bool] = get_or_create_object(database, ConstraintsModel, str_constraints_key)
    db_constraints, created = result

    db_objects = [(db_constraints, created)]

    for position,grpc_constraint in enumerate(grpc_constraints):
        result : Tuple[ConstraintModel, bool] = set_constraint(database, db_constraints, grpc_constraint, position)
        db_constraint, updated = result
        db_objects.append((db_constraint, updated))

    return db_objects