Skip to content

Fixes for #208 and #209 #214

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

Merged
merged 2 commits into from
Feb 6, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion include/SchemaLoader.h
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,6 @@ struct OutputField
{
std::string_view type;
std::string_view name;
std::string_view cppName;
InputFieldList arguments;
OutputFieldType fieldType = OutputFieldType::Builtin;
TypeModifierStack modifiers;
Expand Down Expand Up @@ -263,6 +262,9 @@ class SchemaLoader
std::string getInputCppType(const InputField& field) const noexcept;
std::string getOutputCppType(const OutputField& field) const noexcept;

static std::string getOutputCppAccessor(const OutputField& field) noexcept;
static std::string getOutputCppResolver(const OutputField& field) noexcept;

private:
static bool isExtension(const peg::ast_node& definition) noexcept;

Expand Down Expand Up @@ -303,6 +305,8 @@ class SchemaLoader
void validateTransitiveInterfaces(
std::string_view typeName, const std::vector<std::string_view>& interfaces) const;

static std::string getJoinedCppName(std::string_view prefix, std::string_view fieldName) noexcept;

static const std::string_view s_introspectionNamespace;
static const BuiltinTypeMap s_builtinTypes;
static const CppTypeMap s_builtinCppTypes;
Expand Down
2 changes: 2 additions & 0 deletions include/graphqlservice/GraphQLService.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include "graphqlservice/internal/Version.h"

#include <chrono>
#include <condition_variable>
#include <functional>
#include <future>
#include <list>
Expand All @@ -37,6 +38,7 @@
#include <stdexcept>
#include <string>
#include <string_view>
#include <thread>
#include <tuple>
#include <type_traits>
#include <variant>
Expand Down
8 changes: 8 additions & 0 deletions samples/client/query/QueryClient.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -404,6 +404,9 @@ const std::string& GetRequestText() noexcept
isNow
}
}

# Try a field with a C++ keyword
default
}
)gql"s;

Expand Down Expand Up @@ -459,6 +462,11 @@ Response parseResponse(response::Value response)
result.anyType = ModifiedResponse<Response::anyType_UnionType>::parse<TypeModifier::List, TypeModifier::Nullable>(std::move(member.second));
continue;
}
if (member.first == R"js(default)js"sv)
{
result.default_ = ModifiedResponse<std::string>::parse<TypeModifier::Nullable>(std::move(member.second));
continue;
}
}
}

Expand Down
4 changes: 4 additions & 0 deletions samples/client/query/QueryClient.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,9 @@ static_assert(graphql::internal::MinorVersion == 1, "regenerate with clientgen:
/// isNow
/// }
/// }
///
/// # Try a field with a C++ keyword
/// default
/// }
/// </code>
namespace graphql::client::query::Query {
Expand Down Expand Up @@ -174,6 +177,7 @@ struct Response
unreadCounts_FolderConnection unreadCounts {};
TaskState testTaskState {};
std::vector<std::optional<anyType_UnionType>> anyType {};
std::optional<std::string> default_ {};
};

Response parseResponse(response::Value response);
Expand Down
3 changes: 3 additions & 0 deletions samples/client/query/query.today.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -55,4 +55,7 @@ query {
isNow
}
}

# Try a field with a C++ keyword
default
}
5 changes: 5 additions & 0 deletions samples/today/TodayMock.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -569,6 +569,11 @@ std::vector<std::shared_ptr<object::UnionType>> Query::getAnyType(
return result;
}

std::optional<std::string> Query::getDefault() const noexcept
{
return std::nullopt;
}

Mutation::Mutation(completeTaskMutation&& mutateCompleteTask)
: _mutateCompleteTask(std::move(mutateCompleteTask))
{
Expand Down
1 change: 1 addition & 0 deletions samples/today/TodayMock.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ class Query : public std::enable_shared_from_this<Query>
TaskState getTestTaskState();
std::vector<std::shared_ptr<object::UnionType>> getAnyType(
const service::FieldParams& params, const std::vector<response::IdType>& ids);
std::optional<std::string> getDefault() const noexcept;

private:
std::shared_ptr<Appointment> findAppointment(
Expand Down
14 changes: 13 additions & 1 deletion samples/today/nointrospection/QueryObject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ service::ResolverMap Query::getResolvers() const noexcept
{ R"gql(tasks)gql"sv, [this](service::ResolverParams&& params) { return resolveTasks(std::move(params)); } },
{ R"gql(nested)gql"sv, [this](service::ResolverParams&& params) { return resolveNested(std::move(params)); } },
{ R"gql(anyType)gql"sv, [this](service::ResolverParams&& params) { return resolveAnyType(std::move(params)); } },
{ R"gql(default)gql"sv, [this](service::ResolverParams&& params) { return resolveDefault(std::move(params)); } },
{ R"gql(expensive)gql"sv, [this](service::ResolverParams&& params) { return resolveExpensive(std::move(params)); } },
{ R"gql(tasksById)gql"sv, [this](service::ResolverParams&& params) { return resolveTasksById(std::move(params)); } },
{ R"gql(__typename)gql"sv, [this](service::ResolverParams&& params) { return resolve_typename(std::move(params)); } },
Expand Down Expand Up @@ -231,6 +232,16 @@ service::AwaitableResolver Query::resolveAnyType(service::ResolverParams&& param
return service::ModifiedResult<UnionType>::convert<service::TypeModifier::List, service::TypeModifier::Nullable>(std::move(result), std::move(params));
}

service::AwaitableResolver Query::resolveDefault(service::ResolverParams&& params) const
{
std::unique_lock resolverLock(_resolverMutex);
auto directives = std::move(params.fieldDirectives);
auto result = _pimpl->getDefault(service::FieldParams(service::SelectionSetParams{ params }, std::move(directives)));
resolverLock.unlock();

return service::ModifiedResult<std::string>::convert<service::TypeModifier::Nullable>(std::move(result), std::move(params));
}

service::AwaitableResolver Query::resolve_typename(service::ResolverParams&& params) const
{
return service::ModifiedResult<std::string>::convert(std::string{ R"gql(Query)gql" }, std::move(params));
Expand Down Expand Up @@ -277,7 +288,8 @@ void AddQueryDetails(const std::shared_ptr<schema::ObjectType>& typeQuery, const
schema::Field::Make(R"gql(testTaskState)gql"sv, R"md()md"sv, std::nullopt, schema->WrapType(introspection::TypeKind::NON_NULL, schema->LookupType(R"gql(TaskState)gql"sv))),
schema::Field::Make(R"gql(anyType)gql"sv, R"md()md"sv, std::nullopt, schema->WrapType(introspection::TypeKind::NON_NULL, schema->WrapType(introspection::TypeKind::LIST, schema->LookupType(R"gql(UnionType)gql"sv))), {
schema::InputValue::Make(R"gql(ids)gql"sv, R"md()md"sv, schema->WrapType(introspection::TypeKind::NON_NULL, schema->WrapType(introspection::TypeKind::LIST, schema->WrapType(introspection::TypeKind::NON_NULL, schema->LookupType(R"gql(ID)gql"sv)))), R"gql()gql"sv)
})
}),
schema::Field::Make(R"gql(default)gql"sv, R"md()md"sv, std::nullopt, schema->LookupType(R"gql(String)gql"sv))
});
}

Expand Down
30 changes: 30 additions & 0 deletions samples/today/nointrospection/QueryObject.h
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,18 @@ concept getAnyType = requires (TImpl impl, std::vector<response::IdType> idsArg)
{ service::AwaitableObject<std::vector<std::shared_ptr<UnionType>>> { impl.getAnyType(std::move(idsArg)) } };
};

template <class TImpl>
concept getDefaultWithParams = requires (TImpl impl, service::FieldParams params)
{
{ service::AwaitableScalar<std::optional<std::string>> { impl.getDefault(std::move(params)) } };
};

template <class TImpl>
concept getDefault = requires (TImpl impl)
{
{ service::AwaitableScalar<std::optional<std::string>> { impl.getDefault() } };
};

template <class TImpl>
concept beginSelectionSet = requires (TImpl impl, const service::SelectionSetParams params)
{
Expand Down Expand Up @@ -187,6 +199,7 @@ class Query final
service::AwaitableResolver resolveExpensive(service::ResolverParams&& params) const;
service::AwaitableResolver resolveTestTaskState(service::ResolverParams&& params) const;
service::AwaitableResolver resolveAnyType(service::ResolverParams&& params) const;
service::AwaitableResolver resolveDefault(service::ResolverParams&& params) const;

service::AwaitableResolver resolve_typename(service::ResolverParams&& params) const;

Expand All @@ -209,6 +222,7 @@ class Query final
virtual service::AwaitableObject<std::vector<std::shared_ptr<Expensive>>> getExpensive(service::FieldParams&& params) const = 0;
virtual service::AwaitableScalar<TaskState> getTestTaskState(service::FieldParams&& params) const = 0;
virtual service::AwaitableObject<std::vector<std::shared_ptr<UnionType>>> getAnyType(service::FieldParams&& params, std::vector<response::IdType>&& idsArg) const = 0;
virtual service::AwaitableScalar<std::optional<std::string>> getDefault(service::FieldParams&& params) const = 0;
};

template <class T>
Expand Down Expand Up @@ -412,6 +426,22 @@ class Query final
}
}

service::AwaitableScalar<std::optional<std::string>> getDefault(service::FieldParams&& params) const final
{
if constexpr (methods::QueryHas::getDefaultWithParams<T>)
{
return { _pimpl->getDefault(std::move(params)) };
}
else if constexpr (methods::QueryHas::getDefault<T>)
{
return { _pimpl->getDefault() };
}
else
{
throw std::runtime_error(R"ex(Query::getDefault is not implemented)ex");
}
}

void beginSelectionSet(const service::SelectionSetParams& params) const final
{
if constexpr (methods::QueryHas::beginSelectionSet<T>)
Expand Down
3 changes: 3 additions & 0 deletions samples/today/schema.today.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ type Query {
testTaskState: TaskState!

anyType(ids: [ID!]!): [UnionType]!

"Test C++ keyword names"
default: String
}

"Node interface for Relay support"
Expand Down
14 changes: 13 additions & 1 deletion samples/today/schema/QueryObject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ service::ResolverMap Query::getResolvers() const noexcept
{ R"gql(__type)gql"sv, [this](service::ResolverParams&& params) { return resolve_type(std::move(params)); } },
{ R"gql(nested)gql"sv, [this](service::ResolverParams&& params) { return resolveNested(std::move(params)); } },
{ R"gql(anyType)gql"sv, [this](service::ResolverParams&& params) { return resolveAnyType(std::move(params)); } },
{ R"gql(default)gql"sv, [this](service::ResolverParams&& params) { return resolveDefault(std::move(params)); } },
{ R"gql(__schema)gql"sv, [this](service::ResolverParams&& params) { return resolve_schema(std::move(params)); } },
{ R"gql(expensive)gql"sv, [this](service::ResolverParams&& params) { return resolveExpensive(std::move(params)); } },
{ R"gql(tasksById)gql"sv, [this](service::ResolverParams&& params) { return resolveTasksById(std::move(params)); } },
Expand Down Expand Up @@ -235,6 +236,16 @@ service::AwaitableResolver Query::resolveAnyType(service::ResolverParams&& param
return service::ModifiedResult<UnionType>::convert<service::TypeModifier::List, service::TypeModifier::Nullable>(std::move(result), std::move(params));
}

service::AwaitableResolver Query::resolveDefault(service::ResolverParams&& params) const
{
std::unique_lock resolverLock(_resolverMutex);
auto directives = std::move(params.fieldDirectives);
auto result = _pimpl->getDefault(service::FieldParams(service::SelectionSetParams{ params }, std::move(directives)));
resolverLock.unlock();

return service::ModifiedResult<std::string>::convert<service::TypeModifier::Nullable>(std::move(result), std::move(params));
}

service::AwaitableResolver Query::resolve_typename(service::ResolverParams&& params) const
{
return service::ModifiedResult<std::string>::convert(std::string{ R"gql(Query)gql" }, std::move(params));
Expand Down Expand Up @@ -295,7 +306,8 @@ void AddQueryDetails(const std::shared_ptr<schema::ObjectType>& typeQuery, const
schema::Field::Make(R"gql(testTaskState)gql"sv, R"md()md"sv, std::nullopt, schema->WrapType(introspection::TypeKind::NON_NULL, schema->LookupType(R"gql(TaskState)gql"sv))),
schema::Field::Make(R"gql(anyType)gql"sv, R"md()md"sv, std::nullopt, schema->WrapType(introspection::TypeKind::NON_NULL, schema->WrapType(introspection::TypeKind::LIST, schema->LookupType(R"gql(UnionType)gql"sv))), {
schema::InputValue::Make(R"gql(ids)gql"sv, R"md()md"sv, schema->WrapType(introspection::TypeKind::NON_NULL, schema->WrapType(introspection::TypeKind::LIST, schema->WrapType(introspection::TypeKind::NON_NULL, schema->LookupType(R"gql(ID)gql"sv)))), R"gql()gql"sv)
})
}),
schema::Field::Make(R"gql(default)gql"sv, R"md(Test C++ keyword names)md"sv, std::nullopt, schema->LookupType(R"gql(String)gql"sv))
});
}

Expand Down
30 changes: 30 additions & 0 deletions samples/today/schema/QueryObject.h
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,18 @@ concept getAnyType = requires (TImpl impl, std::vector<response::IdType> idsArg)
{ service::AwaitableObject<std::vector<std::shared_ptr<UnionType>>> { impl.getAnyType(std::move(idsArg)) } };
};

template <class TImpl>
concept getDefaultWithParams = requires (TImpl impl, service::FieldParams params)
{
{ service::AwaitableScalar<std::optional<std::string>> { impl.getDefault(std::move(params)) } };
};

template <class TImpl>
concept getDefault = requires (TImpl impl)
{
{ service::AwaitableScalar<std::optional<std::string>> { impl.getDefault() } };
};

template <class TImpl>
concept beginSelectionSet = requires (TImpl impl, const service::SelectionSetParams params)
{
Expand Down Expand Up @@ -187,6 +199,7 @@ class Query final
service::AwaitableResolver resolveExpensive(service::ResolverParams&& params) const;
service::AwaitableResolver resolveTestTaskState(service::ResolverParams&& params) const;
service::AwaitableResolver resolveAnyType(service::ResolverParams&& params) const;
service::AwaitableResolver resolveDefault(service::ResolverParams&& params) const;

service::AwaitableResolver resolve_typename(service::ResolverParams&& params) const;
service::AwaitableResolver resolve_schema(service::ResolverParams&& params) const;
Expand All @@ -213,6 +226,7 @@ class Query final
virtual service::AwaitableObject<std::vector<std::shared_ptr<Expensive>>> getExpensive(service::FieldParams&& params) const = 0;
virtual service::AwaitableScalar<TaskState> getTestTaskState(service::FieldParams&& params) const = 0;
virtual service::AwaitableObject<std::vector<std::shared_ptr<UnionType>>> getAnyType(service::FieldParams&& params, std::vector<response::IdType>&& idsArg) const = 0;
virtual service::AwaitableScalar<std::optional<std::string>> getDefault(service::FieldParams&& params) const = 0;
};

template <class T>
Expand Down Expand Up @@ -416,6 +430,22 @@ class Query final
}
}

service::AwaitableScalar<std::optional<std::string>> getDefault(service::FieldParams&& params) const final
{
if constexpr (methods::QueryHas::getDefaultWithParams<T>)
{
return { _pimpl->getDefault(std::move(params)) };
}
else if constexpr (methods::QueryHas::getDefault<T>)
{
return { _pimpl->getDefault() };
}
else
{
throw std::runtime_error(R"ex(Query::getDefault is not implemented)ex");
}
}

void beginSelectionSet(const service::SelectionSetParams& params) const final
{
if constexpr (methods::QueryHas::beginSelectionSet<T>)
Expand Down
1 change: 0 additions & 1 deletion src/GraphQLService.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
#include <algorithm>
#include <array>
#include <iostream>
#include <thread>

namespace graphql::service {

Expand Down
Loading