graphql-php/benchmarks/Utils/QueryGenerator.php

106 lines
2.8 KiB
PHP
Raw Normal View History

<?php
namespace GraphQL\Benchmarks\Utils;
use GraphQL\Language\AST\DocumentNode;
use GraphQL\Language\AST\FieldNode;
use GraphQL\Language\AST\NameNode;
use GraphQL\Language\AST\OperationDefinitionNode;
use GraphQL\Language\AST\SelectionSetNode;
use GraphQL\Language\Printer;
use GraphQL\Type\Definition\FieldDefinition;
use GraphQL\Type\Definition\InterfaceType;
use GraphQL\Type\Definition\ObjectType;
use GraphQL\Type\Definition\WrappingType;
use GraphQL\Type\Schema;
use GraphQL\Utils\Utils;
2018-11-27 13:22:29 +03:00
use function count;
use function max;
use function round;
class QueryGenerator
{
private $schema;
private $maxLeafFields;
private $currentLeafFields;
public function __construct(Schema $schema, $percentOfLeafFields)
{
$this->schema = $schema;
Utils::invariant(0 < $percentOfLeafFields && $percentOfLeafFields <= 1);
$totalFields = 0;
foreach ($schema->getTypeMap() as $type) {
2018-11-27 13:22:29 +03:00
if (! ($type instanceof ObjectType)) {
continue;
}
2018-11-27 13:22:29 +03:00
$totalFields += count($type->getFields());
}
2018-11-27 13:22:29 +03:00
$this->maxLeafFields = max(1, round($totalFields * $percentOfLeafFields));
$this->currentLeafFields = 0;
}
public function buildQuery()
{
$qtype = $this->schema->getQueryType();
$ast = new DocumentNode([
2018-11-27 13:22:29 +03:00
'definitions' => [new OperationDefinitionNode([
'name' => new NameNode(['value' => 'TestQuery']),
'operation' => 'query',
'selectionSet' => $this->buildSelectionSet($qtype->getFields()),
]),
],
]);
return Printer::doPrint($ast);
}
/**
* @param FieldDefinition[] $fields
2018-11-27 13:22:29 +03:00
*
* @return SelectionSetNode
*/
public function buildSelectionSet($fields)
{
$selections[] = new FieldNode([
2018-11-27 13:22:29 +03:00
'name' => new NameNode(['value' => '__typename']),
]);
$this->currentLeafFields++;
foreach ($fields as $field) {
if ($this->currentLeafFields >= $this->maxLeafFields) {
break;
}
$type = $field->getType();
if ($type instanceof WrappingType) {
$type = $type->getWrappedType(true);
}
if ($type instanceof ObjectType || $type instanceof InterfaceType) {
$selectionSet = $this->buildSelectionSet($type->getFields());
} else {
$selectionSet = null;
$this->currentLeafFields++;
}
$selections[] = new FieldNode([
'name' => new NameNode(['value' => $field->name]),
2018-11-27 13:22:29 +03:00
'selectionSet' => $selectionSet,
]);
}
$selectionSet = new SelectionSetNode([
2018-11-27 13:22:29 +03:00
'selections' => $selections,
]);
return $selectionSet;
}
}