Example #1
0
 def __compile_function(self, function):
     parameters = []
     for param in function.function_parameters:
         cparam = CompiledExpression(param, user_functions=self.user_functions,
                                     known_variables=self.__all_known_variables)
         parameters.append(cparam)
         self.__collect_attributes( cparam.getDependencies() )
     function.function_parameters = tuple(parameters)
Example #2
0
    def __init__(self, name, attribute_value_select,
                 user_functions={}, known_variables={}):
        self.name = name
        self.attributes = attributes = {}

        self.reverse_deps = reverse_deps = {}
        for (attr, value) in attribute_value_select.iteritems():
            if value:
                expr = CompiledExpression(value, user_functions=user_functions,
                                          known_variables=known_variables)
                dependencies = expr.getDependencies()
            else:
                expr = None
                dependencies = (attr,)

            attributes[attr] = expr
            for attribute in dependencies:
                deps = reverse_deps.get(attribute)
                if deps is None:
                    deps = set()
                    reverse_deps[attribute] = deps
                deps.add(attr)
Example #3
0
    def __init__(self, parsed_viewdef, user_functions={}, new_name=None,
                 new_parents=None, **variable_defaults):
        "Semantically check the view spec, compile it, store it."

        self.user_functions = user_functions
        self.view_name      = new_name or parsed_viewdef.view_name
        self.view_parents   = new_parents or parsed_viewdef.view_parents

        self.select_distinct = distinct = parsed_viewdef.select_distinct
        self.select_buckets  = parsed_viewdef.select_buckets

        # we create new variables here to make different specs independent
        self.loops = [ (Variable(str(var.name)), values)
                       for (var,values) in parsed_viewdef.loops ]
        self.loop_variables = [ loop[0] for loop in self.loops ]

        self.__all_known_variables = dict( (var,var) for var in self.loop_variables )

        # compile and evaluate default values of view variables
        self.variable_options = {}
        for variable in parsed_viewdef.variable_options:
            if variable in self.__all_known_variables:
                raise AmbiguousNameError, variable

            if variable.name in variable_defaults:
                value = variable_defaults[variable.name]
            elif variable.default_value:
                val_exp = CompiledExpression(variable.default_value,
                                             user_functions=user_functions,
                                             known_variables=self.__all_known_variables)
                value = val_exp.evaluate()
            else:
                value = None

            variable = Variable(variable.name, value)
            self.variable_options[variable]      = variable
            self.__all_known_variables[variable] = variable

        # build view interface
        self.view_object = ViewObjectSpec(
            self.view_name, parsed_viewdef.view_attributes,
            user_functions=user_functions,
            known_variables=self.__all_known_variables )

        self.object_select  = parsed_viewdef.object_select
        self.qos_statements = parsed_viewdef.qos_statements

        # prepare __all_attributes to collect all attribute dependencies
        self.__all_attributes = {}
        for obj in self.object_select.keys():
            if obj in self.__all_known_variables:
                # duplicate declaration!
                raise AmbiguousNameError, obj
            self.__all_attributes[obj] = set()

        # compile expression for 'where' and 'having'
        self.where_expression = CompiledExpression(
            parsed_viewdef.where_expression,
            user_functions=user_functions,
            known_variables=self.__all_known_variables
            )
        self.having_expression = CompiledExpression(
            parsed_viewdef.having_expression,
            user_functions=user_functions,
            known_variables=self.__all_known_variables
            )

        # compile expressions in object selector
        for object_name, rank_function in self.object_select.iteritems():
            if object_name in self.__all_known_variables:
                raise AmbiguousNameError, object_name
            self.__compile_rank_function(rank_function, object_name, distinct)

        # find and verify attribute names in created view and where expression
        self.__collect_attributes( self.view_object.all_dependencies() )
        self.__collect_attributes( self.where_expression.getDependencies() )

        self.__dependencies = tuple(sorted( chain(*self.__all_attributes.values()) ))

        # check dependencies of qos statements
        qos_attributes = set(chain(*[ st[1] for st in self.qos_statements ]))
        unresolved_dependencies = qos_attributes - frozenset(self.__dependencies)
        for unknown_attribute in unresolved_dependencies:
            raise UnknownReferenceError, (unknown_attribute, self.__dependencies)

        # compile and evaluate qos statements
        self.__qos_functions = {}
        for qos_function, qos_attributes in self.qos_statements:
            self.__compile_function(qos_function)
            for target_attribute in qos_attributes:
                functions = self.__qos_functions.get(target_attribute)
                if not functions:
                    functions = self.__qos_functions[target_attribute] = []
                functions.append(qos_function)

        select_string = ','.join(sorted('%s[%s]' % item for item in self.object_select.iteritems()))
        self.__hash = hash( (str(self.view_object),
                             self.select_distinct, self.select_buckets,
                             select_string, self.view_parents,
                             self.where_expression) )
Example #4
0
class ViewSpecification(object):
    """This is the compiled representation of a view specification.
    View specifications are guaranteed not to interfere with each other,
    i.e. variables and options are cloned.
    """
    _view_functions = ViewFunctions
    def __init__(self, parsed_viewdef, user_functions={}, new_name=None,
                 new_parents=None, **variable_defaults):
        "Semantically check the view spec, compile it, store it."

        self.user_functions = user_functions
        self.view_name      = new_name or parsed_viewdef.view_name
        self.view_parents   = new_parents or parsed_viewdef.view_parents

        self.select_distinct = distinct = parsed_viewdef.select_distinct
        self.select_buckets  = parsed_viewdef.select_buckets

        # we create new variables here to make different specs independent
        self.loops = [ (Variable(str(var.name)), values)
                       for (var,values) in parsed_viewdef.loops ]
        self.loop_variables = [ loop[0] for loop in self.loops ]

        self.__all_known_variables = dict( (var,var) for var in self.loop_variables )

        # compile and evaluate default values of view variables
        self.variable_options = {}
        for variable in parsed_viewdef.variable_options:
            if variable in self.__all_known_variables:
                raise AmbiguousNameError, variable

            if variable.name in variable_defaults:
                value = variable_defaults[variable.name]
            elif variable.default_value:
                val_exp = CompiledExpression(variable.default_value,
                                             user_functions=user_functions,
                                             known_variables=self.__all_known_variables)
                value = val_exp.evaluate()
            else:
                value = None

            variable = Variable(variable.name, value)
            self.variable_options[variable]      = variable
            self.__all_known_variables[variable] = variable

        # build view interface
        self.view_object = ViewObjectSpec(
            self.view_name, parsed_viewdef.view_attributes,
            user_functions=user_functions,
            known_variables=self.__all_known_variables )

        self.object_select  = parsed_viewdef.object_select
        self.qos_statements = parsed_viewdef.qos_statements

        # prepare __all_attributes to collect all attribute dependencies
        self.__all_attributes = {}
        for obj in self.object_select.keys():
            if obj in self.__all_known_variables:
                # duplicate declaration!
                raise AmbiguousNameError, obj
            self.__all_attributes[obj] = set()

        # compile expression for 'where' and 'having'
        self.where_expression = CompiledExpression(
            parsed_viewdef.where_expression,
            user_functions=user_functions,
            known_variables=self.__all_known_variables
            )
        self.having_expression = CompiledExpression(
            parsed_viewdef.having_expression,
            user_functions=user_functions,
            known_variables=self.__all_known_variables
            )

        # compile expressions in object selector
        for object_name, rank_function in self.object_select.iteritems():
            if object_name in self.__all_known_variables:
                raise AmbiguousNameError, object_name
            self.__compile_rank_function(rank_function, object_name, distinct)

        # find and verify attribute names in created view and where expression
        self.__collect_attributes( self.view_object.all_dependencies() )
        self.__collect_attributes( self.where_expression.getDependencies() )

        self.__dependencies = tuple(sorted( chain(*self.__all_attributes.values()) ))

        # check dependencies of qos statements
        qos_attributes = set(chain(*[ st[1] for st in self.qos_statements ]))
        unresolved_dependencies = qos_attributes - frozenset(self.__dependencies)
        for unknown_attribute in unresolved_dependencies:
            raise UnknownReferenceError, (unknown_attribute, self.__dependencies)

        # compile and evaluate qos statements
        self.__qos_functions = {}
        for qos_function, qos_attributes in self.qos_statements:
            self.__compile_function(qos_function)
            for target_attribute in qos_attributes:
                functions = self.__qos_functions.get(target_attribute)
                if not functions:
                    functions = self.__qos_functions[target_attribute] = []
                functions.append(qos_function)

        select_string = ','.join(sorted('%s[%s]' % item for item in self.object_select.iteritems()))
        self.__hash = hash( (str(self.view_object),
                             self.select_distinct, self.select_buckets,
                             select_string, self.view_parents,
                             self.where_expression) )

    def _multi_loop_iterator(self, loops, value_dict):
        if not loops:
            yield ()
        else:
            variable, values = loops[0]
            variable_name = variable.name
            for loop_values in self._multi_loop_iterator(loops[1:], value_dict):
                for value in values:
                    if hasattr(value, 'evaluate'):
                        value = value.evaluate(value_dict)
                    variable.value = value
                    value_dict[variable_name] = value
                    yield loop_values + (value,)

    def iter_loop_variables(self, value_dict=None):
        """Builds an iterator that returns one tuple for each combination of
        values of the loop variables. It returns () if there are no loops.

        The optional dictionary argument is filled with variable-value pairs.
        Note that these must not be changed outside the iterator."""
        if value_dict is None:
            value_dict = {}
        return self._multi_loop_iterator(self.loops, value_dict)

    def __compile_rank_function(self, function, object_name, distinct):
        if function is None:
            return

        view_function_class = self._view_functions
        if function.name not in view_function_class.VALID_FUNCTIONS:
            raise UnknownReferenceError(function.name, view_function_class.VALID_FUNCTIONS)

        self.__compile_function(function)

        view_functions = view_function_class(object_name)
        build_function = getattr(view_functions, function.name)
        function.setFunction( build_function(distinct=distinct, *function.function_parameters) )

    def __compile_function(self, function):
        parameters = []
        for param in function.function_parameters:
            cparam = CompiledExpression(param, user_functions=self.user_functions,
                                        known_variables=self.__all_known_variables)
            parameters.append(cparam)
            self.__collect_attributes( cparam.getDependencies() )
        function.function_parameters = tuple(parameters)

    def __collect_attributes(self, attributes):
        "Verify that object refences have been declared."
        for attribute in attributes:
            object_name = attribute.object_name
            if object_name in self.__all_known_variables:
                continue
            object_attributes = self.__all_attributes.get(object_name, None)
            if object_attributes is None:
                raise UnknownReferenceError(object_name, self.__all_attributes.keys())
            else:
                object_attributes.add(attribute)

    def getDependencies(self):
        return self.__dependencies

    def getObjectDependencies(self):
        objects = self.__all_attributes.keys()
        objects.sort()
        return objects

    def getQoSParameters(self):
        return self.__qos_functions

    def __hash__(self):
        return self.__hash