Skip to content

Commit 6e6ab2c

Browse files
committed
fix: Reduced no. of iterations in default schema binding
1 parent 5152e94 commit 6e6ab2c

File tree

4 files changed

+71
-53
lines changed

4 files changed

+71
-53
lines changed
Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,45 @@
1-
from graphql import GraphQLSchema
1+
from graphql import GraphQLSchema, GraphQLType
2+
3+
import frappe
4+
from frappe.model.meta import Meta
25

36
from .root_query import setup_root_query_resolvers
47
from .link_field import setup_link_field_resolvers
58
from .child_tables import setup_child_table_resolvers
9+
from .utils import get_singular_doctype
610

711

812
def setup_default_resolvers(schema: GraphQLSchema):
913
setup_root_query_resolvers(schema=schema)
10-
setup_link_field_resolvers(schema=schema)
11-
setup_select_field_resolvers(schema=schema)
12-
setup_child_table_resolvers(schema=schema)
14+
15+
# Setup custom resolvers for DocTypes
16+
for type_name, gql_type in schema.type_map.items():
17+
dt = get_singular_doctype(type_name)
18+
if not dt:
19+
continue
20+
21+
meta = frappe.get_meta(dt)
22+
23+
setup_frappe_df(meta, gql_type)
24+
setup_link_field_resolvers(meta, gql_type)
25+
setup_select_field_resolvers(meta, gql_type)
26+
setup_child_table_resolvers(meta, gql_type)
27+
28+
29+
def setup_frappe_df(meta: Meta, gql_type: GraphQLType):
30+
"""
31+
Sets up frappe-DocField on the GraphQLFields as `frappe_df`.
32+
This is useful when resolving:
33+
- Link / Dynamic Link Fields
34+
- Child Tables
35+
- Checking if the leaf-node is translatable
36+
"""
37+
for df in meta.fields:
38+
if df.fieldname not in gql_type.fields:
39+
continue
40+
41+
gql_type.fields[df.fieldname].frappe_df = df
1342

1443

15-
def setup_select_field_resolvers(schema: GraphQLSchema):
44+
def setup_select_field_resolvers(meta: Meta, gql_type: GraphQLType):
1645
pass

frappe_graphql/utils/resolver/child_tables.py

Lines changed: 9 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,18 @@
1-
from graphql import GraphQLSchema, GraphQLResolveInfo
1+
from graphql import GraphQLType, GraphQLResolveInfo
22

3-
import frappe
3+
from frappe.model.meta import Meta
44

55
from .dataloaders import get_child_table_loader
6-
from .utils import get_singular_doctype
6+
from .utils import get_frappe_df_from_resolve_info
77

88

9-
def setup_child_table_resolvers(schema: GraphQLSchema):
10-
for type_name, gql_type in schema.type_map.items():
11-
dt = get_singular_doctype(type_name)
12-
if not dt:
9+
def setup_child_table_resolvers(meta: Meta, gql_type: GraphQLType):
10+
for df in meta.get_table_fields():
11+
if df.fieldname not in gql_type.fields:
1312
continue
1413

15-
meta = frappe.get_meta(dt)
16-
for df in meta.get_table_fields():
17-
if df.fieldname not in gql_type.fields:
18-
continue
19-
20-
gql_field = gql_type.fields[df.fieldname]
21-
gql_field.frappe_docfield = df
22-
gql_field.resolve = _child_table_resolver
14+
gql_field = gql_type.fields[df.fieldname]
15+
gql_field.resolve = _child_table_resolver
2316

2417

2518
def _child_table_resolver(obj, info: GraphQLResolveInfo, **kwargs):
@@ -28,7 +21,7 @@ def _child_table_resolver(obj, info: GraphQLResolveInfo, **kwargs):
2821
if obj.get(info.field_name) is not None:
2922
return obj.get(info.field_name)
3023

31-
df = getattr(info.parent_type.fields[info.field_name], "frappe_docfield", None)
24+
df = get_frappe_df_from_resolve_info(info)
3225
if not df:
3326
return []
3427

frappe_graphql/utils/resolver/link_field.py

Lines changed: 22 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,40 @@
1-
from graphql import GraphQLSchema, GraphQLResolveInfo
1+
from graphql import GraphQLResolveInfo, GraphQLType
22

33
import frappe
4+
from frappe.model.meta import Meta
45

56
from .dataloaders import get_doctype_dataloader
6-
from .utils import get_singular_doctype
7+
from .utils import get_frappe_df_from_resolve_info
78

89

9-
def setup_link_field_resolvers(schema: GraphQLSchema):
10+
def setup_link_field_resolvers(meta: Meta, gql_type: GraphQLType):
1011
"""
1112
This will set up Link fields on DocTypes to resolve target docs
1213
"""
13-
for type_name, gql_type in schema.type_map.items():
14-
dt = get_singular_doctype(type_name)
15-
if not dt:
16-
continue
17-
18-
meta = frappe.get_meta(dt)
19-
link_dfs = meta.get_link_fields() + meta.get_dynamic_link_fields() + \
20-
_get_default_field_links()
14+
link_dfs = meta.get_link_fields() + meta.get_dynamic_link_fields() + \
15+
_get_default_field_links()
2116

22-
for df in link_dfs:
23-
if df.fieldname not in gql_type.fields:
24-
continue
17+
for df in link_dfs:
18+
if df.fieldname not in gql_type.fields:
19+
continue
2520

26-
gql_field = gql_type.fields[df.fieldname]
27-
gql_field.frappe_docfield = df
28-
if df.fieldtype == "Link":
29-
gql_field.resolve = _resolve_link_field
30-
elif df.fieldtype == "Dynamic Link":
31-
gql_field.resolve = _resolve_dynamic_link_field
32-
else:
33-
continue
21+
gql_field = gql_type.fields[df.fieldname]
22+
if df.fieldtype == "Link":
23+
gql_field.resolve = _resolve_link_field
24+
elif df.fieldtype == "Dynamic Link":
25+
gql_field.resolve = _resolve_dynamic_link_field
26+
else:
27+
continue
3428

35-
_name_df = f"{df.fieldname}__name"
36-
if _name_df not in gql_type.fields:
37-
continue
29+
_name_df = f"{df.fieldname}__name"
30+
if _name_df not in gql_type.fields:
31+
continue
3832

39-
gql_type.fields[_name_df].resolve = _resolve_link_name_field
33+
gql_type.fields[_name_df].resolve = _resolve_link_name_field
4034

4135

4236
def _resolve_link_field(obj, info: GraphQLResolveInfo, **kwargs):
43-
df = _get_frappe_docfield_from_resolve_info(info)
37+
df = get_frappe_df_from_resolve_info(info)
4438
if not df:
4539
return None
4640

@@ -55,7 +49,7 @@ def _resolve_link_field(obj, info: GraphQLResolveInfo, **kwargs):
5549

5650

5751
def _resolve_dynamic_link_field(obj, info: GraphQLResolveInfo, **kwargs):
58-
df = _get_frappe_docfield_from_resolve_info(info)
52+
df = get_frappe_df_from_resolve_info(info)
5953
if not df:
6054
return None
6155

@@ -76,10 +70,6 @@ def _resolve_link_name_field(obj, info: GraphQLResolveInfo, **kwargs):
7670
return obj.get(df)
7771

7872

79-
def _get_frappe_docfield_from_resolve_info(info: GraphQLResolveInfo):
80-
return getattr(info.parent_type.fields[info.field_name], "frappe_docfield", None)
81-
82-
8373
def _get_default_field_links():
8474

8575
def _get_default_field_df(fieldname):

frappe_graphql/utils/resolver/utils.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
from graphql import GraphQLResolveInfo
2+
13
import frappe
24

35
SINGULAR_DOCTYPE_MAP_REDIS_KEY = "singular_doctype_graphql_map"
@@ -42,3 +44,7 @@ def get_plural_doctype(name):
4244
frappe.cache().set_value(PLURAL_DOCTYPE_MAP_REDIS_KEY, plural_map)
4345

4446
return plural_map.get(name, None)
47+
48+
49+
def get_frappe_df_from_resolve_info(info: GraphQLResolveInfo):
50+
return getattr(info.parent_type.fields[info.field_name], "frappe_df", None)

0 commit comments

Comments
 (0)