From 20f8cab9431b0ed4cc8caacab8004e48cd657d63 Mon Sep 17 00:00:00 2001 From: Vladimir Razuvaev Date: Mon, 14 Aug 2017 01:42:02 +0700 Subject: [PATCH] Removed schema descriptor (as lazy loading of types can work without it now) --- benchmarks/HugeSchemaBench.php | 7 -- src/Executor/Executor.php | 2 +- src/Type/Descriptor.php | 61 ---------------- src/Type/Schema.php | 124 +++++++++++---------------------- src/Type/SchemaConfig.php | 48 ++++--------- src/Utils/TypeInfo.php | 2 +- tests/Type/DefinitionTest.php | 2 +- 7 files changed, 58 insertions(+), 188 deletions(-) delete mode 100644 src/Type/Descriptor.php diff --git a/benchmarks/HugeSchemaBench.php b/benchmarks/HugeSchemaBench.php index d0cce0f..7146e7f 100644 --- a/benchmarks/HugeSchemaBench.php +++ b/benchmarks/HugeSchemaBench.php @@ -21,11 +21,6 @@ class HugeSchemaBench */ private $schemaBuilder; - /** - * @var \GraphQL\Type\Descriptor - */ - private $descriptor; - private $schema; private $lazySchema; @@ -47,7 +42,6 @@ class HugeSchemaBench $this->schema = $this->schemaBuilder->buildSchema(); $queryBuilder = new QueryGenerator($this->schema, 0.05); - $this->descriptor = $this->schema->describe(); $this->smallQuery = $queryBuilder->buildQuery(); } @@ -80,7 +74,6 @@ class HugeSchemaBench return new Schema( \GraphQL\Type\SchemaConfig::create() ->setQuery($this->schemaBuilder->buildQueryType()) - // ->setDescriptor($this->descriptor) ->setTypeLoader(function($name) { return $this->schemaBuilder->loadType($name); }) diff --git a/src/Executor/Executor.php b/src/Executor/Executor.php index 0a62d78..5ac9733 100644 --- a/src/Executor/Executor.php +++ b/src/Executor/Executor.php @@ -1062,7 +1062,7 @@ class Executor $runtimeType = $returnType->resolveType($result, $exeContext->contextValue, $info); if (null === $runtimeType) { - if ($returnType instanceof InterfaceType && !$exeContext->schema->getConfig()->descriptor) { + if ($returnType instanceof InterfaceType) { Warning::warnOnce( "GraphQL Interface Type `{$returnType->name}` returned `null` from it`s `resolveType` function ". 'for value: ' . Utils::printSafe($result) . '. Switching to slow resolution method using `isTypeOf` ' . diff --git a/src/Type/Descriptor.php b/src/Type/Descriptor.php deleted file mode 100644 index 39e98cf..0000000 --- a/src/Type/Descriptor.php +++ /dev/null @@ -1,61 +0,0 @@ - $this->typeMap, - 'version' => $this->version, - 'possibleTypeMap' => $this->possibleTypeMap, - 'created' => $this->created - ]; - } - - /** - * Specify data which should be serialized to JSON - * @link http://php.net/manual/en/jsonserializable.jsonserialize.php - * @return mixed data which can be serialized by json_encode, - * which is a value of any type other than a resource. - * @since 5.4.0 - */ - function jsonSerialize() - { - return $this->toArray(); - } -} diff --git a/src/Type/Schema.php b/src/Type/Schema.php index 4909e49..3623da4 100644 --- a/src/Type/Schema.php +++ b/src/Type/Schema.php @@ -49,13 +49,6 @@ class Schema */ private $config; - /** - * Contains actual descriptor for this schema - * - * @var Descriptor - */ - private $descriptor; - /** * Contains currently resolved schema types * @@ -63,6 +56,11 @@ class Schema */ private $resolvedTypes = []; + /** + * @var array + */ + private $possibleTypeMap; + /** * True when $resolvedTypes contain all possible schema types * @@ -104,8 +102,7 @@ class Schema 'subscription', 'types', 'directives', - 'typeLoader', - 'descriptor' + 'typeLoader' ]), Utils::getVariableType($config) ); @@ -116,6 +113,15 @@ class Schema ); $this->config = $config; + + $this->resolvedTypes[$config->query->name] = $config->query; + + if ($config->mutation) { + $this->resolvedTypes[$config->mutation->name] = $config->mutation; + } + if ($config->subscription) { + $this->resolvedTypes[$config->subscription->name] = $config->subscription; + } } /** @@ -165,15 +171,7 @@ class Schema public function getTypeMap() { if (!$this->fullyLoaded) { - if ($this->config->descriptor && $this->config->typeLoader) { - // Following is still faster than $this->collectAllTypes() because it won't init fields - $typesToResolve = array_diff_key($this->config->descriptor->typeMap, $this->resolvedTypes); - foreach ($typesToResolve as $typeName => $_) { - $this->resolvedTypes[$typeName] = $this->loadType($typeName); - } - } else { - $this->resolvedTypes = $this->collectAllTypes(); - } + $this->resolvedTypes = $this->collectAllTypes(); $this->fullyLoaded = true; } return $this->resolvedTypes; @@ -190,51 +188,11 @@ class Schema return $this->resolveType($name); } - /** - * Returns serializable schema descriptor which can be passed later - * to Schema config to enable a set of performance optimizations - * - * @return Descriptor - */ - public function describe() - { - if ($this->descriptor) { - return $this->descriptor; - } - - $this->resolvedTypes = $this->collectAllTypes(); - $this->fullyLoaded = true; - - $descriptor = new Descriptor(); - $descriptor->version = '1.0'; - $descriptor->created = time(); - - foreach ($this->resolvedTypes as $type) { - if ($type instanceof ObjectType) { - foreach ($type->getInterfaces() as $interface) { - $descriptor->possibleTypeMap[$interface->name][$type->name] = 1; - } - } else if ($type instanceof UnionType) { - foreach ($type->getTypes() as $innerType) { - $descriptor->possibleTypeMap[$type->name][$innerType->name] = 1; - } - } - $descriptor->typeMap[$type->name] = 1; - } - - return $this->descriptor = $descriptor; - } - private function collectAllTypes() { $initialTypes = array_merge( - [ - $this->config->query, - $this->config->mutation, - $this->config->subscription, - Introspection::_schema() - ], - array_values($this->resolvedTypes) + array_values($this->resolvedTypes), + [Introspection::_schema()] ); $typeMap = []; @@ -276,20 +234,30 @@ class Schema */ public function getPossibleTypes(AbstractType $abstractType) { - if ($abstractType instanceof UnionType) { - return $abstractType->getTypes(); - } + $possibleTypeMap = $this->getPossibleTypeMap(); + return array_values($possibleTypeMap[$abstractType->name]); + } - /** @var InterfaceType $abstractType */ - $descriptor = $this->config->descriptor ?: $this->describe(); - - $result = []; - if (isset($descriptor->possibleTypeMap[$abstractType->name])) { - foreach ($descriptor->possibleTypeMap[$abstractType->name] as $typeName => $_) { - $result[] = $this->resolveType($typeName); + /** + * @return array + */ + private function getPossibleTypeMap() + { + if ($this->possibleTypeMap === null) { + $this->possibleTypeMap = []; + foreach ($this->getTypeMap() as $type) { + if ($type instanceof ObjectType) { + foreach ($type->getInterfaces() as $interface) { + $this->possibleTypeMap[$interface->name][$type->name] = $type; + } + } else if ($type instanceof UnionType) { + foreach ($type->getTypes() as $innerType) { + $this->possibleTypeMap[$type->name][$innerType->name] = $innerType; + } + } } } - return $result; + return $this->possibleTypeMap; } /** @@ -336,10 +304,6 @@ class Schema */ public function isPossibleType(AbstractType $abstractType, ObjectType $possibleType) { - if ($this->config->descriptor) { - return !empty($this->config->descriptor->possibleTypeMap[$abstractType->name][$possibleType->name]); - } - if ($abstractType instanceof InterfaceType) { return $possibleType->implementsInterface($abstractType); } @@ -381,14 +345,8 @@ class Schema private function defaultTypeLoader($typeName) { // Default type loader simply fallbacks to collecting all types - if (!$this->fullyLoaded) { - $this->resolvedTypes = $this->collectAllTypes(); - $this->fullyLoaded = true; - } - if (!isset($this->resolvedTypes[$typeName])) { - return null; - } - return $this->resolvedTypes[$typeName]; + $typeMap = $this->getTypeMap(); + return isset($typeMap[$typeName]) ? $typeMap[$typeName] : null; } diff --git a/src/Type/SchemaConfig.php b/src/Type/SchemaConfig.php index 07efb3c..96e9db3 100644 --- a/src/Type/SchemaConfig.php +++ b/src/Type/SchemaConfig.php @@ -1,8 +1,6 @@ setDirectives($options['directives']); } + if (isset($options['typeResolution'])) { + trigger_error( + 'Type resolution strategies are deprecated. Just pass single option `typeLoader` '. + 'to schema constructor instead.', + E_USER_DEPRECATED + ); + if ($options['typeResolution'] instanceof Resolution && !isset($options['typeLoader'])) { + $strategy = $options['typeResolution']; + $options['typeLoader'] = function($name) use ($strategy) { + return $strategy->resolveType($name); + }; + } + } + if (isset($options['typeLoader'])) { Utils::invariant( is_callable($options['typeLoader']), @@ -113,15 +120,6 @@ class SchemaConfig ); $config->setTypeLoader($options['typeLoader']); } - - if (isset($options['descriptor'])) { - Utils::invariant( - $options['descriptor'] instanceof Descriptor, - 'Schema descriptor must be instance of GraphQL\Type\Descriptor but got: %s', - Utils::getVariableType($options['descriptor']) - ); - $config->setDescriptor($options['descriptor']); - } } return $config; @@ -217,24 +215,6 @@ class SchemaConfig return $this; } - /** - * @return Descriptor - */ - public function getDescriptor() - { - return $this->descriptor; - } - - /** - * @param Descriptor $descriptor - * @return SchemaConfig - */ - public function setDescriptor(Descriptor $descriptor) - { - $this->descriptor = $descriptor; - return $this; - } - /** * @return callable */ diff --git a/src/Utils/TypeInfo.php b/src/Utils/TypeInfo.php index 4edfc00..4cc09d4 100644 --- a/src/Utils/TypeInfo.php +++ b/src/Utils/TypeInfo.php @@ -106,7 +106,7 @@ class TypeInfo } if (!$type instanceof Type) { Warning::warnOnce( - 'One of schema types is not a valid type definition instance. Ignoring it. '. + 'One of the schema types is not a valid type definition instance. '. 'Try running $schema->assertValid() to find out the cause of this warning.', Warning::NOT_A_TYPE ); diff --git a/tests/Type/DefinitionTest.php b/tests/Type/DefinitionTest.php index a363685..7510bd7 100644 --- a/tests/Type/DefinitionTest.php +++ b/tests/Type/DefinitionTest.php @@ -577,7 +577,7 @@ class DefinitionTest extends \PHPUnit_Framework_TestCase ]); $this->assertFalse($called); - $schema->getType('Query'); + $schema->getType('Blog'); $this->assertTrue($called); $this->assertEquals([$node], $blog->getInterfaces());