def match(x): if isinstance(x, dict): result = [{}] for n, e in p.items(): if n in x: result = [ sat.cmb(c, d) for c in result for d in e(x[n]) if sat.cmp(c, d) ] elif n in q: result = [ sat.cmb(c, d) for c in result for d in e(q[n]) if sat.cmp(c, d) ] else: return [] if r is not None: y = {k: v for k, v in x.items() if k not in p} result = [ sat.cmb(c, d) for c in result for d in r(y) if sat.cmp(c, d) ] return result else: return []
def q(c, x): for d in f(): if sat.cmp(c, d): for n, e, y in p(sat.cmb(c, d), x): yield n, e, y else: yield False, '(constraint)', x
def p(c, x): v = '' y = x while len(y) > 0 and y[0] not in r: d = sat.ctx(k, f(v)) if sat.cmp(c, d): yield True, sat.cmb(c, d), y # note: not yielding a failure here, because it would be either: # - unnecessary because of a match at the end # - identical to the failure yielded at the end v = v + y[0] y = y[1:] d = sat.ctx(k, f(v)) if sat.cmp(c, d): yield True, sat.cmb(c, d), y else: yield False, sat.get(k, c), x
def match(x): if isinstance(x, dict): return [ sat.cmb(kz, vz) for ky, vy in x.items() for kz in ke(ky) for vz in ve(vy) if sat.cmp(kz, vz) ] else: return []
def _load(self, input_result, file_format, file_path, target_expression): if file_path.data == 'target_constant': file_list = [json.loads(file_path.children[0])] elif file_path.data == 'target_template': if isinstance(file_path.children[0], str): prefix = re.sub(r'^`|^}|`$|\${$', '', file_path.children[0]) else: prefix = '' file_list = glob.glob(prefix + '*') else: raise Exception( f'Loading from node of type {file_path.data} not supported') compiled_path = self._compile_target(file_path) compiled_target = self._compile_target(target_expression) for context in input_result: for file in file_list: for match in compiled_path(file.replace('\\', '/')): if sat.cmp(context, match): subcontext = sat.cmb(context, match) with open(file, encoding='UTF-8') as fp: if file_format == 'JSON': source_value = json.load(fp) yield from ( sat.cmb(subcontext, match) for match in compiled_target(source_value) if sat.cmp(subcontext, match)) elif file_format == 'JSONL': for line in fp: source_value = json.loads(line) yield from (sat.cmb(subcontext, match) for match in compiled_target( source_value) if sat.cmp(subcontext, match)) elif file_format == 'TEXT': for line in fp: source_value = line[:-1] if line.endswith( '\n') else line yield from (sat.cmb(subcontext, match) for match in compiled_target( source_value) if sat.cmp(subcontext, match)) else: raise Exception( f'File format {file_format} not supported')
def _match(self, input_result, target_expression): compiled_target = self._compile_target(target_expression) for context in input_result: yield from (sat.cmb(context, match) for i, record in self._candidate_records( target_expression, context) for match in compiled_target(record) if sat.cmp(context, match))
def als(e, k): """ Destructure a value using expression e, assigning te original value to alias k >>> e = als(lit('foo'), 'foo') >>> e('bar') [] >>> e('foo') [{'foo': 'foo'}] """ return lambda x: [ sat.cmb(c, d) for c in e(x) for d in [sat.ctx(k, x)] if sat.cmp(c, d) ]
def match(x): if isinstance(x, list): result = [{}] for i, e in enumerate(es): if len(x) > i: result = [ sat.cmb(c, d) for c in result for d in e(x[i]) if sat.cmp(c, d) ] else: return [] return result else: return []
def _merge(self, input_result, source_expression, target_expression): compiled_projection, target_expression = self._compile_merge_projection( source_expression, target_expression) # compiled_source = self._compile_source(source_expression) compiled_target = self._compile_target(target_expression) # TODO: first generate changeset so that changes are isolated from reading query??? for patch, context in compiled_projection(input_result): for i, record in self._candidate_records(target_expression, context): if any( sat.cmp(context, match) for match in compiled_target(record)): self._records[i] = sat.cmb(record, patch) self._update_indexes() return None
def _delete(self, input_result, target_expression): compiled_target = self._compile_target(target_expression) delete_set = set() for context in input_result: for i, record in self._candidate_records(target_expression, context): if any( sat.cmp(context, match) for match in compiled_target(record)): delete_set |= {i} self._records = [ record for i, record in enumerate(self._records) if i not in delete_set ] self._update_indexes() return None