def evaluate_i(self, static, dynamic, local): left = utils.get_single(self.left.evaluate(static, dynamic, local)) right = utils.get_single(self.right.evaluate(static, dynamic, local)) if left.jpath_type != right.jpath_type: raise e.TypeException( "Left and right values to the ++ operator " "have to be of the same type, but the left value was of " "type " + str(type(left)) + " and the right value was of " "type " + str(type(right)) ) if isinstance(left, d.String): # String concatenation return utils.singleton(d.StandardString(left.get_value() + right.get_value())) if isinstance(left, d.List): # List concatenation return utils.singleton(d.StandardList(left.to_python_list() + right.to_python_list())) if isinstance(left, d.Object): # Object union; take the object on the # left side, create a new copy of it, then update it with the # pairs of the object on the right side. The right side should # override the left side in the case of a key conflict. dictionary = {} for k, v in left: dictionary[k] = v for k, v in right: dictionary[k] = v return utils.singleton(d.StandardObject([d.StandardPair(k, v) for k, v in dictionary.iteritems()])) raise e.TypeException( "Values of type " + str(type(left)) + " can't " "be concatenated using the ++ operator. Only values of type " "string, list, or object can be given to ++. To convert " "values to strings, you can use the string() function." )
def call_function(self, dynamic_context, args): """ Calls this module as a function, which runs the module's main code. Args is the empty list to call a module, I.E. modules don't require any JPath function arguments. A single, optional argument can, however, be provided in this list; it should be a JPath sequence containing exactly one value, a JPath object. The keys of this object will be used as the names of variables to predefine when running this module, and the values will be used as the values of the variables. (For now, this means that all variable values will end up being singleton sequences; I might add some way around this in the future.) """ if len(args) == 0: local_context = None else: sequence = args[0] dictionary = sequence.get_item(0) var_map = {} for pair in dictionary: key, value = pair.get_key().get_value(), pair.get_value() if not isinstance(key, (str, unicode)): raise TypeError(type(key)) var_map[key] = utils.singleton(value) local_context = context.LocalContext().new(set_map=var_map) return self.main_function.call_function(dynamic_context, [], local_context)
def evaluate_i(self, static, dynamic, local): value = utils.get_single(self.value.evaluate(static, dynamic, local)) reference = utils.get_single(self.reference.evaluate(static, dynamic, local)) if isinstance(self.position, Production): position = self.position.evaluate(static, dynamic, local) position = utils.get_single_instance(position, d.Number).get_as_int() else: position = self.position return utils.singleton(d.StandardInsert(value, reference, position))
def run_query(self, query, update, vars={}): """ Runs the specified query string. The semantics of this method are the same as run_module, except that the query text is specified as a parameter to this method. """ interpreter = self.interpreter_constructor() module = interpreter.get_binder("jpath").create_query(query) wrapped_vars = utils.singleton(translate.json_to_jpath(vars)) result = module.call_with_values(self.make_context(), [wrapped_vars]) result = self.process_result(result, update) return result
def query(jpath_query, json={}, vars={}, interpreter=None, as_tuple=False): if interpreter is None: interpreter = Interpreter() module = interpreter.get_binder("jpath").create_query(jpath_query) wrapped_vars = utils.singleton(translate.json_to_jpath(vars)) result = module.call_with_values( context.DynamicContext(translate.json_to_jpath(json), 1, 1), [wrapped_vars]) if len(result) == 0 and not as_tuple: return None elif len(result) == 1 and not as_tuple: return translate.jpath_to_json(utils.get_single(result)) else: return tuple(translate.jpath_to_json(v) for v in result)
def root(dynamic): function = dynamic.userland.get("db.get_root", None) if function is None: raise e.OtherException("Query is not running in the context of a " "database, so the root function cannot be called. " "Specifically, the dynamic context userland does not have an " "entry named db.get_root; this should be a function that " "returns the root database object.") root = function() if not isinstance(root, d.Item): raise e.OtherException("Dynamic context userland db.get_root " "function returned a value that was not an instance of Item; " "specifically, it was an instance of " + str(type(root))) return utils.singleton(root)
def run_module(self, module, update, vars={}): """ Runs the named module as a main module. The specified dictionary of variables are set just before calling the module; they can be accessed as $foo, $bar, etc., for vars={"foo": ..., "bar": ...}. If update is True, the module's result is assumed to be a sequence of zero or more updates, which are applied to the database. If update is False, the result of the module, whether or not it's a sequence of updates, is returned as-is. If update is None, it will be treated as if it were true if the result of the module is a sequence of updates and false otherwise. """ interpreter = self.interpreter_constructor() module = interpreter.bind_module("jpath", module) wrapped_vars = utils.singleton(translate.json_to_jpath(vars)) result = module.call_with_values(self.make_context(), [wrapped_vars]) result = self.process_result(result, update) return result
def get_for_pair_indexer(self, value): result = self.get_pair(utils.get_single(value)) if result is None: return EmptySequence() return utils.singleton(result)
def get_for_pair_pattern(self, pattern): value = self.get_pair(StandardString(pattern)) if value is None: return EmptySequence() return utils.singleton(value)
def evaluate_i(self, static, dynamic, local): return singleton(d.StandardNull())
def evaluate_i(self, static, dynamic, local): return singleton(d.StandardBoolean(self.value))
def evaluate_i(self, static, dynamic, local): source = self.source.evaluate(static, dynamic, local) target = self.target.evaluate(static, dynamic, local) return utils.singleton(d.StandardMerge(source, target))
def evaluate_i(self, static, dynamic, local): target = self.target.evaluate(static, dynamic, local) replacement = self.replacement.evaluate(static, dynamic, local) return utils.singleton(d.StandardReplace(target, replacement))
def evaluate_i(self, static, dynamic, local): value = self.expr.evaluate(static, dynamic, local) return utils.singleton(d.StandardDelete(value))
def string(dynamic, value): return utils.singleton(d.StandardString(utils.get_single(value).to_string()))
def input(dynamic): return utils.singleton(d.StandardString(raw_input()))