mirror of
https://github.com/retailcrm/graphql-php.git
synced 2024-11-24 22:06:04 +03:00
160 lines
4.6 KiB
PHP
160 lines
4.6 KiB
PHP
<?php
|
|
namespace GraphQL\Benchmarks\Utils;
|
|
|
|
use GraphQL\Schema;
|
|
use GraphQL\Type\Definition\EnumType;
|
|
use GraphQL\Type\Definition\InputObjectType;
|
|
use GraphQL\Type\Definition\ObjectType;
|
|
use GraphQL\Type\Definition\Type;
|
|
|
|
class SchemaGenerator
|
|
{
|
|
private $config = [
|
|
'totalTypes' => 100,
|
|
'nestingLevel' => 10,
|
|
'fieldsPerType' => 10,
|
|
'listFieldsPerType' => 2
|
|
];
|
|
|
|
private $typeIndex = 0;
|
|
|
|
private $objectTypes = [];
|
|
|
|
/**
|
|
* BenchmarkSchemaBuilder constructor.
|
|
* @param array $config
|
|
*/
|
|
public function __construct(array $config)
|
|
{
|
|
$this->config = array_merge($this->config, $config);
|
|
}
|
|
|
|
public function buildSchema()
|
|
{
|
|
return new Schema([
|
|
'query' => $this->buildQueryType()
|
|
]);
|
|
}
|
|
|
|
public function buildQueryType()
|
|
{
|
|
$this->typeIndex = 0;
|
|
$this->objectTypes = [];
|
|
|
|
return $this->createType(0);
|
|
}
|
|
|
|
public function loadType($name)
|
|
{
|
|
$tokens = explode('_', $name);
|
|
$nestingLevel = (int) $tokens[1];
|
|
|
|
return $this->createType($nestingLevel, $name);
|
|
}
|
|
|
|
protected function createType($nestingLevel, $typeName = null)
|
|
{
|
|
if ($this->typeIndex > $this->config['totalTypes']) {
|
|
throw new \Exception(
|
|
"Cannot create new type: there are already {$this->typeIndex} ".
|
|
"which exceeds allowed number of {$this->config['totalTypes']} types total"
|
|
);
|
|
}
|
|
|
|
$this->typeIndex++;
|
|
if (!$typeName) {
|
|
$typeName = 'Level_' . $nestingLevel . '_Type' . $this->typeIndex;
|
|
}
|
|
|
|
$type = new ObjectType([
|
|
'name' => $typeName,
|
|
'fields' => function() use ($typeName, $nestingLevel) {
|
|
return $this->createTypeFields($typeName, $nestingLevel + 1);
|
|
}
|
|
]);
|
|
|
|
$this->objectTypes[$typeName] = $type;
|
|
return $type;
|
|
}
|
|
|
|
protected function getFieldTypeAndName($nestingLevel, $fieldIndex)
|
|
{
|
|
if ($nestingLevel >= $this->config['nestingLevel']) {
|
|
$fieldType = Type::string();
|
|
$fieldName = 'leafField' . $fieldIndex;
|
|
} else if ($this->typeIndex >= $this->config['totalTypes']) {
|
|
$fieldType = $this->objectTypes[array_rand($this->objectTypes)];
|
|
$fieldName = 'randomTypeField' . $fieldIndex;
|
|
} else {
|
|
$fieldType = $this->createType($nestingLevel);
|
|
$fieldName = 'field' . $fieldIndex;
|
|
}
|
|
|
|
return [$fieldType, $fieldName];
|
|
}
|
|
|
|
protected function createTypeFields($typeName, $nestingLevel)
|
|
{
|
|
$fields = [];
|
|
for ($index = 0; $index < $this->config['fieldsPerType']; $index++) {
|
|
list($type, $name) = $this->getFieldTypeAndName($nestingLevel, $index);
|
|
$fields[] = [
|
|
'name' => $name,
|
|
'type' => $type,
|
|
'resolve' => [$this, 'resolveField']
|
|
];
|
|
}
|
|
for ($index = 0; $index < $this->config['listFieldsPerType']; $index++) {
|
|
list($type, $name) = $this->getFieldTypeAndName($nestingLevel, $index);
|
|
$name = 'listOf' . ucfirst($name);
|
|
|
|
$fields[] = [
|
|
'name' => $name,
|
|
'type' => Type::listOf($type),
|
|
'args' => $this->createFieldArgs($name, $typeName),
|
|
'resolve' => function() {
|
|
return [
|
|
'string1',
|
|
'string2',
|
|
'string3',
|
|
'string4',
|
|
'string5',
|
|
];
|
|
}
|
|
];
|
|
}
|
|
return $fields;
|
|
}
|
|
|
|
protected function createFieldArgs($fieldName, $typeName)
|
|
{
|
|
return [
|
|
'argString' => [
|
|
'type' => Type::string()
|
|
],
|
|
'argEnum' => [
|
|
'type' => new EnumType([
|
|
'name' => $typeName . $fieldName . 'Enum',
|
|
'values' => [
|
|
"ONE", "TWO", "THREE"
|
|
]
|
|
])
|
|
],
|
|
'argInputObject' => [
|
|
'type' => new InputObjectType([
|
|
'name' => $typeName . $fieldName . 'Input',
|
|
'fields' => [
|
|
'field1' => Type::string(),
|
|
'field2' => Type::int()
|
|
]
|
|
])
|
|
]
|
|
];
|
|
}
|
|
|
|
public function resolveField($value, $args, $context, $resolveInfo)
|
|
{
|
|
return $resolveInfo->fieldName . '-value';
|
|
}
|
|
}
|