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) )