コード例 #1
0
ファイル: viewspec.py プロジェクト: BackupTheBerlios/slow-svn
    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) )