Skip to content

Commit f605261

Browse files
committed
fix: patch introspection resolvers in Object::StitchObject
1 parent 29376f2 commit f605261

File tree

2 files changed

+55
-16
lines changed

2 files changed

+55
-16
lines changed

include/graphqlservice/GraphQLService.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -830,7 +830,8 @@ class [[nodiscard("unnecessary construction")]] Object : public std::enable_shar
830830
GRAPHQLSERVICE_EXPORT virtual ~Object() = default;
831831

832832
[[nodiscard("unnecessary call")]] GRAPHQLSERVICE_EXPORT std::shared_ptr<Object> StitchObject(
833-
const std::shared_ptr<const Object>& added) const;
833+
const std::shared_ptr<const Object>& added,
834+
const std::shared_ptr<schema::Schema>& schema = {}) const;
834835

835836
[[nodiscard("unnecessary call")]] GRAPHQLSERVICE_EXPORT AwaitableResolver resolve(
836837
const SelectionSetParams& selectionSetParams, const peg::ast_node& selection,

src/GraphQLService.cpp

Lines changed: 53 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@
44
#include "graphqlservice/GraphQLService.h"
55

66
#include "graphqlservice/internal/Grammar.h"
7+
#include "graphqlservice/internal/Introspection.h"
8+
9+
#include "graphqlservice/introspection/SchemaObject.h"
10+
#include "graphqlservice/introspection/TypeObject.h"
711

812
#include "Validation.h"
913

@@ -267,17 +271,17 @@ void await_worker_queue::resumePending()
267271
// Default to immediate synchronous execution.
268272
await_async::await_async()
269273
: _pimpl { std::static_pointer_cast<const Concept>(
270-
std::make_shared<Model<std::suspend_never>>(std::make_shared<std::suspend_never>())) }
274+
std::make_shared<Model<std::suspend_never>>(std::make_shared<std::suspend_never>())) }
271275
{
272276
}
273277

274278
// Implicitly convert a std::launch parameter used with std::async to an awaitable.
275279
await_async::await_async(std::launch launch)
276280
: _pimpl { ((launch & std::launch::async) == std::launch::async)
277281
? std::static_pointer_cast<const Concept>(std::make_shared<Model<await_worker_thread>>(
278-
std::make_shared<await_worker_thread>()))
282+
std::make_shared<await_worker_thread>()))
279283
: std::static_pointer_cast<const Concept>(std::make_shared<Model<std::suspend_never>>(
280-
std::make_shared<std::suspend_never>())) }
284+
std::make_shared<std::suspend_never>())) }
281285
{
282286
}
283287

@@ -1253,21 +1257,50 @@ Object::Object(TypeNames&& typeNames, ResolverMap&& resolvers) noexcept
12531257
{
12541258
}
12551259

1256-
std::shared_ptr<Object> Object::StitchObject(const std::shared_ptr<const Object>& added) const
1260+
std::shared_ptr<Object> Object::StitchObject(const std::shared_ptr<const Object>& added,
1261+
const std::shared_ptr<schema::Schema>& schema /* = {} */) const
12571262
{
12581263
auto typeNames = _typeNames;
1264+
auto resolvers = _resolvers;
12591265

1260-
for (const auto& name : added->_typeNames)
1266+
if (schema && schema->supportsIntrospection())
12611267
{
1262-
typeNames.emplace(name);
1268+
resolvers.erase("__schema"sv);
1269+
resolvers.emplace("__schema"sv, [schema](ResolverParams&& params) {
1270+
return Result<Object>::convert(
1271+
std::static_pointer_cast<Object>(std::make_shared<introspection::object::Schema>(
1272+
std::make_shared<introspection::Schema>(schema))),
1273+
std::move(params));
1274+
});
1275+
1276+
resolvers.erase("__type"sv);
1277+
resolvers.emplace("__type"sv, [schema](ResolverParams&& params) {
1278+
auto argName = ModifiedArgument<std::string>::require("name", params.arguments);
1279+
const auto& baseType = schema->LookupType(argName);
1280+
std::shared_ptr<introspection::object::Type> result { baseType
1281+
? std::make_shared<introspection::object::Type>(
1282+
std::make_shared<introspection::Type>(baseType))
1283+
: nullptr };
1284+
1285+
return ModifiedResult<introspection::object::Type>::convert<TypeModifier::Nullable>(
1286+
result,
1287+
std::move(params));
1288+
});
12631289
}
12641290

1265-
auto resolvers = _resolvers;
12661291
bool hasStitchedResolvers = false;
12671292

1268-
for (const auto& [name, resolver] : added->_resolvers)
1293+
if (added)
12691294
{
1270-
hasStitchedResolvers = resolvers.emplace(name, resolver).second || hasStitchedResolvers;
1295+
for (const auto& name : added->_typeNames)
1296+
{
1297+
typeNames.emplace(name);
1298+
}
1299+
1300+
for (const auto& [name, resolver] : added->_resolvers)
1301+
{
1302+
hasStitchedResolvers = resolvers.emplace(name, resolver).second || hasStitchedResolvers;
1303+
}
12711304
}
12721305

12731306
auto object = std::make_shared<Object>(std::move(typeNames), std::move(resolvers));
@@ -1779,24 +1812,30 @@ Request::~Request()
17791812
std::shared_ptr<const Request> Request::stitch(const std::shared_ptr<const Request>& added) const
17801813
{
17811814
TypeMap operations;
1815+
auto schema = _schema->StitchSchema(added->_schema);
1816+
std::shared_ptr<Object> query;
17821817
auto itrOriginalQuery = _operations.find(strQuery);
17831818
auto itrAddedQuery = added->_operations.find(strQuery);
17841819

17851820
if (itrOriginalQuery != _operations.end() && itrOriginalQuery->second)
17861821
{
17871822
if (itrAddedQuery != added->_operations.end() && itrAddedQuery->second)
17881823
{
1789-
operations.emplace(strQuery,
1790-
itrOriginalQuery->second->StitchObject(itrAddedQuery->second));
1824+
query = itrOriginalQuery->second->StitchObject(itrAddedQuery->second, schema);
17911825
}
17921826
else
17931827
{
1794-
operations.emplace(strQuery, itrOriginalQuery->second);
1828+
query = itrOriginalQuery->second->StitchObject({}, schema);
17951829
}
17961830
}
17971831
else if (itrAddedQuery != added->_operations.end() && itrAddedQuery->second)
17981832
{
1799-
operations.emplace(strQuery, itrAddedQuery->second);
1833+
query = itrAddedQuery->second->StitchObject({}, schema);
1834+
}
1835+
1836+
if (query)
1837+
{
1838+
operations.emplace(strQuery, query);
18001839
}
18011840

18021841
auto itrOriginalMutation = _operations.find(strMutation);
@@ -1848,8 +1887,7 @@ std::shared_ptr<const Request> Request::stitch(const std::shared_ptr<const Reque
18481887
}
18491888
};
18501889

1851-
return std::make_shared<StitchedRequest>(std::move(operations),
1852-
_schema->StitchSchema(added->_schema));
1890+
return std::make_shared<StitchedRequest>(std::move(operations), std::move(schema));
18531891
}
18541892

18551893
std::list<schema_error> Request::validate(peg::ast& query) const

0 commit comments

Comments
 (0)