Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Memoize field maps for Objects and Interfaces #265

Merged
merged 2 commits into from Jan 7, 2018
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
54 changes: 38 additions & 16 deletions definition.go
Expand Up @@ -365,9 +365,11 @@ type Object struct {
PrivateDescription string `json:"description"`
IsTypeOf IsTypeOfFn

typeConfig ObjectConfig
fields FieldDefinitionMap
interfaces []*Interface
typeConfig ObjectConfig
initialisedFields bool
fields FieldDefinitionMap
initialisedInterfaces bool
interfaces []*Interface
// Interim alternative to throwing an error during schema definition at run-time
err error
}
Expand Down Expand Up @@ -429,6 +431,7 @@ func (gt *Object) AddFieldConfig(fieldName string, fieldConfig *Field) {
switch gt.typeConfig.Fields.(type) {
case Fields:
gt.typeConfig.Fields.(Fields)[fieldName] = fieldConfig
gt.initialisedFields = false
}
}
func (gt *Object) Name() string {
Expand All @@ -441,20 +444,30 @@ func (gt *Object) String() string {
return gt.PrivateName
}
func (gt *Object) Fields() FieldDefinitionMap {
if gt.initialisedFields {
return gt.fields
}

var configureFields Fields
switch gt.typeConfig.Fields.(type) {
case Fields:
configureFields = gt.typeConfig.Fields.(Fields)
case FieldsThunk:
configureFields = gt.typeConfig.Fields.(FieldsThunk)()
}

fields, err := defineFieldMap(gt, configureFields)
gt.err = err
gt.fields = fields
gt.initialisedFields = true
return gt.fields
}

func (gt *Object) Interfaces() []*Interface {
if gt.initialisedInterfaces {
return gt.interfaces
}

var configInterfaces []*Interface
switch gt.typeConfig.Interfaces.(type) {
case InterfacesThunk:
Expand All @@ -463,14 +476,18 @@ func (gt *Object) Interfaces() []*Interface {
configInterfaces = gt.typeConfig.Interfaces.([]*Interface)
case nil:
default:
gt.err = fmt.Errorf("Unknown Object.Interfaces type: %v", reflect.TypeOf(gt.typeConfig.Interfaces))
gt.err = fmt.Errorf("Unknown Object.Interfaces type: %T", gt.typeConfig.Interfaces)
gt.initialisedInterfaces = true
return nil
}

interfaces, err := defineInterfaces(gt, configInterfaces)
gt.err = err
gt.interfaces = interfaces
gt.initialisedInterfaces = true
return gt.interfaces
}

func (gt *Object) Error() error {
return gt.err
}
Expand Down Expand Up @@ -507,15 +524,7 @@ func defineInterfaces(ttype *Object, interfaces []*Interface) ([]*Interface, err
return ifaces, nil
}

func defineFieldMap(ttype Named, fields interface{}) (FieldDefinitionMap, error) {
var fieldMap Fields
switch fields.(type) {
case Fields:
fieldMap = fields.(Fields)
case FieldsThunk:
fieldMap = fields.(FieldsThunk)()
}

func defineFieldMap(ttype Named, fieldMap Fields) (FieldDefinitionMap, error) {
resultFieldMap := FieldDefinitionMap{}

err := invariant(
Expand Down Expand Up @@ -695,9 +704,10 @@ type Interface struct {
PrivateDescription string `json:"description"`
ResolveType ResolveTypeFn

typeConfig InterfaceConfig
fields FieldDefinitionMap
err error
typeConfig InterfaceConfig
initialisedFields bool
fields FieldDefinitionMap
err error
}
type InterfaceConfig struct {
Name string `json:"name"`
Expand Down Expand Up @@ -751,30 +761,42 @@ func (it *Interface) AddFieldConfig(fieldName string, fieldConfig *Field) {
switch it.typeConfig.Fields.(type) {
case Fields:
it.typeConfig.Fields.(Fields)[fieldName] = fieldConfig
it.initialisedFields = false
}
}

func (it *Interface) Name() string {
return it.PrivateName
}

func (it *Interface) Description() string {
return it.PrivateDescription
}

func (it *Interface) Fields() (fields FieldDefinitionMap) {
if it.initialisedFields {
return it.fields
}

var configureFields Fields
switch it.typeConfig.Fields.(type) {
case Fields:
configureFields = it.typeConfig.Fields.(Fields)
case FieldsThunk:
configureFields = it.typeConfig.Fields.(FieldsThunk)()
}

fields, err := defineFieldMap(it, configureFields)
it.err = err
it.fields = fields
it.initialisedFields = true
return it.fields
}

func (it *Interface) String() string {
return it.PrivateName
}

func (it *Interface) Error() error {
return it.err
}
Expand Down