-
Notifications
You must be signed in to change notification settings - Fork 61
/
Copy pathBuild.php
131 lines (119 loc) · 4.72 KB
/
Build.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
<?php
namespace SilverStripe\GraphQL\Dev;
use SilverStripe\Control\Controller;
use SilverStripe\Control\Director;
use SilverStripe\Control\HTTPRequest;
use SilverStripe\Dev\DebugView;
use SilverStripe\GraphQL\Schema\DataObject\FieldAccessor;
use SilverStripe\GraphQL\Schema\Exception\EmptySchemaException;
use SilverStripe\GraphQL\Schema\Exception\SchemaBuilderException;
use SilverStripe\GraphQL\Schema\Exception\SchemaNotFoundException;
use SilverStripe\GraphQL\Schema\Logger;
use SilverStripe\GraphQL\Schema\Schema;
use SilverStripe\GraphQL\Schema\SchemaBuilder;
use SilverStripe\GraphQL\Schema\Storage\CodeGenerationStore;
use SilverStripe\ORM\Connect\NullDatabaseException;
class Build extends Controller
{
private static $url_handlers = [
'' => 'build'
];
private static $allowed_actions = [
'build'
];
/**
* @param HTTPRequest $request
* @throws SchemaBuilderException
* @throws SchemaNotFoundException
*/
public function build(HTTPRequest $request)
{
$isBrowser = !Director::is_cli();
if ($isBrowser) {
$renderer = DebugView::create();
echo $renderer->renderHeader();
echo $renderer->renderInfo("GraphQL Schema Builder", Director::absoluteBaseURL());
echo "<div class=\"build\">";
}
$clear = true;
$verbosity = strtoupper($request->getVar('verbosity') ?? 'INFO');
$constantRef = sprintf('%s::%s', Logger::class, $verbosity);
Schema::invariant(
defined($constantRef),
'Illegal verbosity: %s',
$verbosity
);
$level = constant($constantRef);
$this->buildSchema($request->getVar('schema'), $clear, $level);
if ($isBrowser) {
echo "</div>";
echo $renderer->renderFooter();
}
}
/**
* @param null $key
* @param bool $clear
* @param int $level
* @throws SchemaNotFoundException
* @throws SchemaBuilderException
*/
public function buildSchema($key = null, $clear = true, int $level = Logger::INFO): void
{
$logger = Logger::singleton();
$logger->setVerbosity($level);
$keys = $key ? [$key] : array_keys(Schema::config()->get('schemas'));
$keys = array_filter($keys, function ($key) {
return $key !== Schema::ALL;
});
// Check for old code dir
if (is_dir(BASE_PATH . '/.graphql')) {
$logger->warning(
'You have a .graphql/ directory in your project root. This is no longer the default
name. The new directory is named ' . CodeGenerationStore::config()->get('dirName') . '. You may
want to delete this directory and update your .gitignore file, if you are ignoring the generated
GraphQL code.'
);
}
foreach ($keys as $key) {
Benchmark::start('build-schema-' . $key);
$logger->info(sprintf('--- Building schema "%s" ---', $key));
$builder = SchemaBuilder::singleton();
try {
$schema = $builder->boot($key);
try {
$builder->build($schema, $clear);
} catch (EmptySchemaException $e) {
$logger->warning('Schema ' . $key . ' is empty. Skipping.');
}
} catch (NullDatabaseException $e) {
$candidate = null;
foreach ($e->getTrace() as $item) {
$class = $item['class'] ?? null;
$function = $item['function'] ?? null;
// This is the only known path to a database query, so we'll offer some help here.
if ($class === FieldAccessor::class && $function === 'accessField') {
$candidate = $item;
break;
}
}
$logger->warning("
Your schema configuration requires access to the database. This can happen
when you add fields that require type introspection (i.e. custom getters).
It is recommended that you specify an explicit type when adding custom getters
to your schema.");
if ($candidate) {
$logger->warning(sprintf(
"
This most likely happened when you tried to add the field '%s' to '%s'",
$candidate['args'][1],
get_class($candidate['args'][0])
));
}
throw $e;
}
$logger->info(
Benchmark::end('build-schema-' . $key, 'Built schema in %sms.')
);
}
}
}