Skip to content

Instantly share code, notes, and snippets.

@hipertracker
Last active January 20, 2022 18:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hipertracker/a3bd064c92477137e2b4ae9717d057e2 to your computer and use it in GitHub Desktop.
Save hipertracker/a3bd064c92477137e2b4ae9717d057e2 to your computer and use it in GitHub Desktop.
import itertools
import json
import re
from typing import List
def group(_input):
d = list(itertools.chain(*list(map(lambda x: list(x.items()), _input))))
_s = [[a, [c for _, c in b]] for a, b in itertools.groupby(sorted(d, key=lambda x: x[0]), key=lambda x: x[0])]
return {a: group(b) if all(isinstance(i, dict) for i in b) else list(itertools.chain(*b)) for a, b in _s}
def fix_values(dic):
for k, v in dic.items():
if isinstance(v, list):
dic[k] = ''.join(v)
else:
fix_values(v)
return dic
def trim(s):
"""clear all white characters"""
return re.sub(r'\s', '', s)
def build_query(items, indent=2):
"""
transform a tree into grqphql query string
"""
dic = build_dict(items)
return re.sub(r'["\s]', '', json.dumps(dic, indent=indent))[1:-1]
def build_dict(items):
"""
transform a list of conditions into dictionary
"""
dicts = []
for item in items:
json_str = '{' + re.sub(r'([$\w]+)', r'"\1"', item) + '}'
dic = json.loads(json_str)
dicts.append(dic)
dic = group(dicts)
return fix_values(dic)
from django.test import TestCase
from .lib import build_dict, build_query, trim
class TestBuildQuery(TestCase):
def test_build_dict(self):
items = [
'aa:{bb:{cc:{f3:{_op3:$f3}}}}', # 1
'aa:{bb:{f2:{_op2:$f2}}}', # 2
'aa:{dd:{f4:{_op4:$f4}}}', # 3
'aa:{bb:{f1:{_op1:$f1}}}', # 1
]
expected = {
'aa': {
'bb': {
'cc': {
'f3': {
'_op3': '$f3'
}
},
'f1': {
'_op1': '$f1'
},
'f2': {
'_op2': '$f2'
},
},
'dd': {
'f4': {
'_op4': '$f4'
}
}
}
}
assert build_dict(items) == expected
def test_build_query(self):
items = [
'aa:{bb:{cc:{f3:{_op3:$f3}}}}', # 1
'aa:{bb:{f2:{_op2:$f2}}}', # 2
'aa:{dd:{f4:{_op4:$f4}}}', # 3
'aa:{bb:{f1:{_op1:$f1}}}', # 1
]
expected = '''
aa: {
bb: {
cc: {f3: {_op3: $f3}},
f1: {_op1: $f1},
f2: {_op2: $f2}
},
dd: {f4: {_op4: $f4}}
}
'''
assert build_query(items) == trim(expected)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment