Skip to content

Commit

Permalink
Add a feature switch to trigger SchemaValidator in Collector
Browse files Browse the repository at this point in the history
Fixes #1115
  • Loading branch information
bastnic committed Jan 6, 2020
1 parent 9a24ae1 commit df47248
Show file tree
Hide file tree
Showing 6 changed files with 75 additions and 56 deletions.
41 changes: 24 additions & 17 deletions DataCollector/DoctrineDataCollector.php
Expand Up @@ -26,9 +26,13 @@ class DoctrineDataCollector extends BaseCollector
/** @var string[] */
private $groupedQueries;

public function __construct(ManagerRegistry $registry)
/** @var bool */
private $shouldValidateSchema;

public function __construct(ManagerRegistry $registry, bool $shouldValidateSchema = true)
{
$this->registry = $registry;
$this->shouldValidateSchema = $shouldValidateSchema;

parent::__construct($registry);
}
Expand Down Expand Up @@ -59,25 +63,28 @@ public function collect(Request $request, Response $response, Throwable $excepti

/** @var EntityManager $em */
foreach ($this->registry->getManagers() as $name => $em) {
$entities[$name] = [];
/** @var ClassMetadataFactory $factory */
$factory = $em->getMetadataFactory();
$validator = new SchemaValidator($em);

/** @var ClassMetadataInfo $class */
foreach ($factory->getLoadedMetadata() as $class) {
if (isset($entities[$name][$class->getName()])) {
continue;
}
if ($this->shouldValidateSchema) {
$entities[$name] = [];

$classErrors = $validator->validateClass($class);
$entities[$name][$class->getName()] = $class->getName();
/** @var ClassMetadataFactory $factory */
$factory = $em->getMetadataFactory();
$validator = new SchemaValidator($em);

if (empty($classErrors)) {
continue;
}
/** @var ClassMetadataInfo $class */
foreach ($factory->getLoadedMetadata() as $class) {
if (isset($entities[$name][$class->getName()])) {
continue;
}

$errors[$name][$class->getName()] = $classErrors;
$classErrors = $validator->validateClass($class);
$entities[$name][$class->getName()] = $class->getName();

if (empty($classErrors)) {
continue;
}

$errors[$name][$class->getName()] = $classErrors;
}
}

/** @var Configuration $emConfig */
Expand Down
4 changes: 4 additions & 0 deletions DependencyInjection/Configuration.php
Expand Up @@ -136,6 +136,10 @@ private function getDbalConnectionsNode()
->defaultValue(false)
->info('Enables collecting backtraces when profiling is enabled')
->end()
->booleanNode('profiling_collect_schema_errors')
->defaultValue(true)
->info('Enables collecting schema errors when profiling is enabled')
->end()
->scalarNode('server_version')->end()
->scalarNode('driver_class')->end()
->scalarNode('wrapper_class')->end()
Expand Down
4 changes: 3 additions & 1 deletion DependencyInjection/DoctrineExtension.php
Expand Up @@ -128,7 +128,9 @@ protected function loadDbalConnection($name, array $connection, ContainerBuilder
$profilingLoggerId = $profilingAbstractId . '.' . $name;
$container->setDefinition($profilingLoggerId, new ChildDefinition($profilingAbstractId));
$profilingLogger = new Reference($profilingLoggerId);
$container->getDefinition('data_collector.doctrine')->addMethodCall('addLogger', [$name, $profilingLogger]);
$container->getDefinition('data_collector.doctrine')
->addMethodCall('addLogger', [$name, $profilingLogger])
->replaceArgument(1, $connection['profiling_collect_schema_errors']);

if ($logger !== null) {
$chainLogger = new ChildDefinition('doctrine.dbal.logger.chain');
Expand Down
1 change: 1 addition & 0 deletions Resources/config/dbal.xml
Expand Up @@ -41,6 +41,7 @@
<service id="data_collector.doctrine" class="%doctrine.data_collector.class%" public="false">
<tag name="data_collector" template="@Doctrine/Collector/db.html.twig" id="db" priority="250" />
<argument type="service" id="doctrine" />
<argument>true</argument>
</service>

<service id="doctrine.dbal.connection_factory" class="%doctrine.dbal.connection_factory.class%">
Expand Down
3 changes: 3 additions & 0 deletions Resources/doc/configuration.rst
Expand Up @@ -105,6 +105,8 @@ Configuration Reference
profiling: "%kernel.debug%"
# When true, profiling also collects a backtrace for each query
profiling_collect_backtrace: false
# When true, profiling also collects schema errors for each query
profiling_collect_schema_errors: true
server_version: ~
driver_class: ~
Expand Down Expand Up @@ -465,6 +467,7 @@ Configuration Reference
logging="%kernel.debug%"
profiling="%kernel.debug%"
profiling-collect-backtrace="false"
profiling-collect-schema-errors="true"
server-version=""
driver-class=""
wrapper-class=""
Expand Down
78 changes: 40 additions & 38 deletions Resources/views/Collector/db.html.twig
Expand Up @@ -387,47 +387,49 @@
{% endif %}
{% endif %}

<h2>Entities Mapping</h2>
{% if collector.entities|length > 0 %}
<h2>Entities Mapping</h2>

{% for manager, classes in collector.entities %}
{% if collector.managers|length > 1 %}
<h3>{{ manager }} <small>entity manager</small></h3>
{% endif %}
{% for manager, classes in collector.entities %}
{% if collector.managers|length > 1 %}
<h3>{{ manager }} <small>entity manager</small></h3>
{% endif %}

{% if classes is empty %}
<div class="empty">
<p>No loaded entities.</p>
</div>
{% else %}
<table>
<thead>
<tr>
<th scope="col">Class</th>
<th scope="col">Mapping errors</th>
</tr>
</thead>
<tbody>
{% for class in classes %}
{% set contains_errors = collector.mappingErrors[manager] is defined and collector.mappingErrors[manager][class] is defined %}
<tr class="{{ contains_errors ? 'status-error' }}">
<td>{{ class }}</td>
<td class="font-normal">
{% if contains_errors %}
<ul>
{% for error in collector.mappingErrors[manager][class] %}
<li>{{ error }}</li>
{% endfor %}
</ul>
{% else %}
No errors.
{% endif %}
</td>
{% if classes is empty %}
<div class="empty">
<p>No loaded entities.</p>
</div>
{% else %}
<table>
<thead>
<tr>
<th scope="col">Class</th>
<th scope="col">Mapping errors</th>
</tr>
{% endfor %}
</tbody>
</table>
{% endif %}
{% endfor %}
</thead>
<tbody>
{% for class in classes %}
{% set contains_errors = collector.mappingErrors[manager] is defined and collector.mappingErrors[manager][class] is defined %}
<tr class="{{ contains_errors ? 'status-error' }}">
<td>{{ class }}</td>
<td class="font-normal">
{% if contains_errors %}
<ul>
{% for error in collector.mappingErrors[manager][class] %}
<li>{{ error }}</li>
{% endfor %}
</ul>
{% else %}
No errors.
{% endif %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endif %}
{% endfor %}
{% endif %}

<script type="text/javascript">//<![CDATA[
function explain(link) {
Expand Down

0 comments on commit df47248

Please sign in to comment.