|
4 | 4 | #include "graphqlservice/GraphQLService.h"
|
5 | 5 |
|
6 | 6 | #include "graphqlservice/internal/Grammar.h"
|
| 7 | +#include "graphqlservice/internal/Introspection.h" |
| 8 | + |
| 9 | +#include "graphqlservice/introspection/SchemaObject.h" |
| 10 | +#include "graphqlservice/introspection/TypeObject.h" |
7 | 11 |
|
8 | 12 | #include "Validation.h"
|
9 | 13 |
|
@@ -267,17 +271,17 @@ void await_worker_queue::resumePending()
|
267 | 271 | // Default to immediate synchronous execution.
|
268 | 272 | await_async::await_async()
|
269 | 273 | : _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>())) } |
271 | 275 | {
|
272 | 276 | }
|
273 | 277 |
|
274 | 278 | // Implicitly convert a std::launch parameter used with std::async to an awaitable.
|
275 | 279 | await_async::await_async(std::launch launch)
|
276 | 280 | : _pimpl { ((launch & std::launch::async) == std::launch::async)
|
277 | 281 | ? 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>())) |
279 | 283 | : 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>())) } |
281 | 285 | {
|
282 | 286 | }
|
283 | 287 |
|
@@ -1253,21 +1257,50 @@ Object::Object(TypeNames&& typeNames, ResolverMap&& resolvers) noexcept
|
1253 | 1257 | {
|
1254 | 1258 | }
|
1255 | 1259 |
|
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 |
1257 | 1262 | {
|
1258 | 1263 | auto typeNames = _typeNames;
|
| 1264 | + auto resolvers = _resolvers; |
1259 | 1265 |
|
1260 |
| - for (const auto& name : added->_typeNames) |
| 1266 | + if (schema && schema->supportsIntrospection()) |
1261 | 1267 | {
|
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 | + }); |
1263 | 1289 | }
|
1264 | 1290 |
|
1265 |
| - auto resolvers = _resolvers; |
1266 | 1291 | bool hasStitchedResolvers = false;
|
1267 | 1292 |
|
1268 |
| - for (const auto& [name, resolver] : added->_resolvers) |
| 1293 | + if (added) |
1269 | 1294 | {
|
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 | + } |
1271 | 1304 | }
|
1272 | 1305 |
|
1273 | 1306 | auto object = std::make_shared<Object>(std::move(typeNames), std::move(resolvers));
|
@@ -1779,24 +1812,30 @@ Request::~Request()
|
1779 | 1812 | std::shared_ptr<const Request> Request::stitch(const std::shared_ptr<const Request>& added) const
|
1780 | 1813 | {
|
1781 | 1814 | TypeMap operations;
|
| 1815 | + auto schema = _schema->StitchSchema(added->_schema); |
| 1816 | + std::shared_ptr<Object> query; |
1782 | 1817 | auto itrOriginalQuery = _operations.find(strQuery);
|
1783 | 1818 | auto itrAddedQuery = added->_operations.find(strQuery);
|
1784 | 1819 |
|
1785 | 1820 | if (itrOriginalQuery != _operations.end() && itrOriginalQuery->second)
|
1786 | 1821 | {
|
1787 | 1822 | if (itrAddedQuery != added->_operations.end() && itrAddedQuery->second)
|
1788 | 1823 | {
|
1789 |
| - operations.emplace(strQuery, |
1790 |
| - itrOriginalQuery->second->StitchObject(itrAddedQuery->second)); |
| 1824 | + query = itrOriginalQuery->second->StitchObject(itrAddedQuery->second, schema); |
1791 | 1825 | }
|
1792 | 1826 | else
|
1793 | 1827 | {
|
1794 |
| - operations.emplace(strQuery, itrOriginalQuery->second); |
| 1828 | + query = itrOriginalQuery->second->StitchObject({}, schema); |
1795 | 1829 | }
|
1796 | 1830 | }
|
1797 | 1831 | else if (itrAddedQuery != added->_operations.end() && itrAddedQuery->second)
|
1798 | 1832 | {
|
1799 |
| - operations.emplace(strQuery, itrAddedQuery->second); |
| 1833 | + query = itrAddedQuery->second->StitchObject({}, schema); |
| 1834 | + } |
| 1835 | + |
| 1836 | + if (query) |
| 1837 | + { |
| 1838 | + operations.emplace(strQuery, query); |
1800 | 1839 | }
|
1801 | 1840 |
|
1802 | 1841 | auto itrOriginalMutation = _operations.find(strMutation);
|
@@ -1848,8 +1887,7 @@ std::shared_ptr<const Request> Request::stitch(const std::shared_ptr<const Reque
|
1848 | 1887 | }
|
1849 | 1888 | };
|
1850 | 1889 |
|
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)); |
1853 | 1891 | }
|
1854 | 1892 |
|
1855 | 1893 | std::list<schema_error> Request::validate(peg::ast& query) const
|
|
0 commit comments