Skip to content

Commit

Permalink
FieldExecutionInfo will only merge selections on request
Browse files Browse the repository at this point in the history
  • Loading branch information
AnthonyMDev committed Sep 21, 2021
1 parent 2c7a167 commit 2b88510
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 13 deletions.
29 changes: 17 additions & 12 deletions Sources/Apollo/GraphQLExecutor.swift
Original file line number Diff line number Diff line change
Expand Up @@ -46,25 +46,31 @@ fileprivate struct ExecutionInfo { // TODO: Rename?
}
}

fileprivate struct FieldSelectionGrouping {
fileprivate struct FieldSelectionGrouping: Sequence {
private var fieldInfoList: [String: FieldExecutionInfo] = [:]

var count: Int { fieldInfoList.count }

mutating func append(field: Selection.Field, withInfo info: ExecutionInfo) {
let fieldKey = field.responseKey
if var fieldInfo = fieldInfoList[fieldKey] {
fieldInfo.mergeInSelections(of: field)
fieldInfo.mergedFields.append(field)
fieldInfoList[fieldKey] = fieldInfo
} else {
fieldInfoList[fieldKey] = FieldExecutionInfo(field: field, info: info)
}
}

func makeIterator() -> Dictionary<String, FieldExecutionInfo>.Iterator {
fieldInfoList.makeIterator()
}
}

struct FieldExecutionInfo {
let field: Selection.Field
private let info: ExecutionInfo

private(set) var selections: [Selection] = []
var mergedFields: [Selection.Field]

let responsePath: ResponsePath
let responseKeyForField: String
Expand All @@ -78,12 +84,11 @@ struct FieldExecutionInfo {
) {
self.field = field
self.info = info
mergedFields = [field]

let responseKey = field.responseKey
responsePath = info.responsePath.appending(responseKey)
responseKeyForField = responseKey

mergeInSelections(of: field)
}

fileprivate mutating func computeCacheKeyAndPath(with variables: [String: JSONEncodable]) throws {
Expand All @@ -92,12 +97,12 @@ struct FieldExecutionInfo {
cacheKeyForField = cacheKey
}

fileprivate mutating func mergeInSelections(of field: Selection.Field) {
// TODO: Can we do this only for fields of object type?
// Hold on to a list of "otherFields" instead of a list of selections, then call a
// `mergeSelections()` function during `complete`, which only has to be called on object fields.
if case let .object(selectionSet) = field.type.namedType {
selections += selectionSet.selections
fileprivate func computeMergedSelections() -> [Selection] {
return mergedFields.flatMap { field -> [Selection] in
guard case let .object(selectionSet) = field.type.namedType else {
return []
}
return selectionSet.selections
}
}
}
Expand Down Expand Up @@ -478,7 +483,7 @@ final class GraphQLExecutor {
let groupedFields = try groupFields(selections, on: object, info: info)

var fieldEntries: [PossiblyDeferred<Accumulator.FieldEntry>] = []
fieldEntries.reserveCapacity(groupedFields.keys.count)
fieldEntries.reserveCapacity(groupedFields.count)

for (_, fields) in groupedFields {
let fieldEntry = execute(fields: fields,
Expand Down
2 changes: 1 addition & 1 deletion Sources/Apollo/GraphQLResponse.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ public final class GraphQLResponse<Data: SelectionSet> {
public let body: JSONObject

private var rootKey: String
private var variables: [String: InputValue]?
private var variables: [String: JsonE]?

public init<Operation: GraphQLOperation>(operation: Operation, body: JSONObject) where Operation.Data == Data {
self.body = body
Expand Down

0 comments on commit 2b88510

Please sign in to comment.