def evaluate_ql_on(ql, state=None, cache=None): """This is equivalent to evaluate_query_on, but accepts decoded query (list of lists of strings).""" if cache is None: cache = get_cache() if state is None: state = State() elif not isinstance(state, State): state = State().with_data(state) cr = command_registry() for i, qcommand in enumerate(ql): if i == len(ql) - 1: if len(qcommand) == 1 and '.' in qcommand[0]: state.with_filename(qcommand[0]) break state = cr.evaluate_command(state, qcommand) if state.caching and not state.is_error and not state.is_volatile(): cache.store(state) return state
def evaluate_action(self, state: State, action, extra_parameters=None, cache=None): self.debug(f"EVALUATE ACTION '{action}' on '{state.query}'") self.status = Status.EVALUATION self.store_metadata(force=True) cache = cache or self.cache() cr = self.command_registry() state.context = self if isinstance(action, TransformQuerySegment): if action.is_filename(): return state.with_filename(action.filename) assert action.is_action_request() action = action.query[0] is_volatile = state.is_volatile() old_state = state if is_volatile else state.clone() state = state.next_state() state.context = self ns, command, cmd_metadata = cr.resolve_command(state, action.name) if command is None: self.error( f"Unknown action: '{action.name}'", position=action.position, query=self.raw_query, ) else: self._metadata.add_command_dependency(ns, cmd_metadata) parameters = [] self.status = Status.EVALUATING_DEPENDENCIES self.store_metadata(force=True) for p in action.parameters: parameters.append(self.evaluate_parameter(p, action)) if extra_parameters is not None and len(extra_parameters) > 0: self.warning(f"Using {len(extra_parameters)} extra parameters") parameters.extend(extra_parameters) is_volatile = True self.status = Status.EVALUATION self.store_metadata(force=True) try: state = command(old_state, *parameters, context=self) assert type(state.metadata) is dict except EvaluationException as ee: print("EE:", ee) # traceback.print_exc() state.is_error = True state.exception = ee except Exception as e: traceback.print_exc() state.is_error = True self.exception( message=str(e), position=action.position, query=self.raw_query, traceback=traceback.format_exc(), ) state.exception = EvaluationException( traceback.format_exc() + "\n" + str(e), position=action.position, query=self.raw_query, ) arguments = getattr(state, "arguments", None) if arguments is not None: def to_arg(arg): x, meta = arg try: s = json.dumps(x) if len(s) > 100: return [s[:50], meta] return [x, meta] except: return [None, meta] arguments = [to_arg(a) for a in arguments] metadata = self.metadata() metadata["type_identifier"] = state.type_identifier metadata["commands"] = metadata.get("commands", []) + [action.to_list()] if metadata.get( "mimetype", "application/octet-stream") == "application/octet-stream": metadata["mimetype"] = state.mimetype() try: cmd_metadata_d = cmd_metadata._asdict() except: cmd_metadata_d = {} metadata["extended_commands"] = metadata.get( "extended_commands", []) + [ dict( command_name=action.name, ns=ns, qcommand=action.to_list(), action=f"{action.encode()} at {action.position}", command_metadata=cmd_metadata_d, arguments=arguments, ) ] metadata["query"] = self.raw_query metadata["attributes"] = { key: value for key, value in state.metadata["attributes"].items() if key[0].isupper() } if cmd_metadata is not None: metadata["attributes"] = dict(metadata.get("attributes", {}), **cmd_metadata.attributes) metadata["caching"] = metadata.get( "caching", True) and state.metadata.get("caching", True) is_error = state.is_error or self.is_error if is_error: self.status = Status.ERROR metadata["status"] = self.status.value self.info(f"Action {action.encode()} at {action.position} failed") state.metadata.update(metadata) state.status = Status.ERROR.value state.is_error = True else: self.status = Status.READY metadata["status"] = self.status.value self.info( f"Action {action.encode()} at {action.position} completed") state_vars = dict(self.vars) state_vars.update(state.vars) state_vars.update(self.vars.get_modified()) self.vars = Vars(state_vars) metadata["vars"] = dict(state_vars) state.metadata.update(metadata) state.set_volatile(is_volatile or state.is_volatile()) cache.store_metadata(state.metadata) return state