Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

merge pomm bridge with pommbundle #104

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,15 @@
"jdorn/sql-formatter": "~1.2",
"pomm-project/model-manager": "~2.0",
"pomm-project/cli": "~2.0",
"pomm-project/pomm-symfony-bridge": "~2.5",
"symfony/framework-bundle": "~2.8|~3.0|~4.0"
},
"require-dev": {
"symfony/console": "~2.6|~3.0|~4.0",
"squizlabs/php_codesniffer": "~2.7"
},
"conflict": {
"pomm-project/pomm-symfony-bridge": "*"
},
"suggest": {
"symfony/web-profiler-bundle": "Display queries log",
"sensio/distribution-bundle": "To use the entity param converter"
Expand Down
51 changes: 51 additions & 0 deletions sources/lib/Configurator/DatabaseCollectorConfigurator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<?php
/*
* This file is part of the PommProject/PommBundle package.
*
* (c) 2018 Grégoire HUBERT <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace PommProject\PommBundle\Configurator;

use PommProject\Foundation\Pomm;
use Symfony\Component\HttpKernel\DataCollector\DataCollector;

/**
* Data collector for the database profiler.
*
* @package PommBundle
* @copyright 2018 Grégoire HUBERT
* @author Paris Mikael
* @license X11 {@link http://opensource.org/licenses/mit-license.php}
* @see DataCollector
*/
class DatabaseCollectorConfigurator
{
protected $datacollector;

public function __construct(DataCollector $datacollector)
{
$this->datacollector = $datacollector;
}

/**
* @param Pomm $pomm
*
* @return null

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

return void

*/
public function configure(Pomm $pomm)
{
$callable = [$this->datacollector, 'execute'];

foreach ($pomm->getSessionBuilders() as $name => $builder) {
$pomm->addPostConfiguration($name, function ($session) use ($callable) {
$session
->getClientUsingPooler('listener', 'query')
->attachAction($callable)
;
});
}
}
}
99 changes: 99 additions & 0 deletions sources/lib/Controller/PommProfilerController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
<?php
/*
* This file is part of the PommProject/PommBundle package.
*
* (c) 2018 Grégoire HUBERT <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace PommProject\PommBundle\Controller;

use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\HttpKernel\Profiler\Profiler;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;

use PommProject\Foundation\Pomm;

/**
* Controllers for the Pomm profiler extension.
*
* @package PommBundle
* @copyright 2018 Grégoire HUBERT
* @author Grégoire HUBERT
* @license X11 {@link http://opensource.org/licenses/mit-license.php}
*/
class PommProfilerController
{
private $generator;
private $profiler;
private $twig;
private $pomm;

public function __construct(
UrlGeneratorInterface $generator,
Profiler $profiler,
\Twig_Environment $twig,
Pomm $pomm
) {
$this->generator = $generator;
$this->profiler = $profiler;
$this->twig = $twig;
$this->pomm = $pomm;
}

/**
* Controller to explain a SQL query.
*
* @param $request
* @param string $token
* @param int $index_query
*
* @return Response
*/
public function explainAction(Request $request, $token, $index_query)
{
$panel = 'pomm';
$page = 'home';

if (!($profile = $this->profiler->loadProfile($token))) {
return new Response(
$this->twig->render(
'@WebProfiler/Profiler/info.html.twig',
array('about' => 'no_token', 'token' => $token)
),
200,
array('Content-Type' => 'text/html')
);
}

$this->profiler->disable();

if (!$profile->hasCollector($panel)) {
throw new NotFoundHttpException(sprintf('Panel "%s" is not available for token "%s".', $panel, $token));
}

if (!array_key_exists($index_query, $profile->getCollector($panel)->getQueries())) {
throw new \InvalidArgumentException(sprintf("No such query index '%s'.", $index_query));
}

$query_data = $profile->getCollector($panel)->getQueries()[$index_query];

$explain = $this->pomm[$query_data['session_stamp']]
->getClientUsingPooler('query_manager', null)
->query(sprintf("explain %s", $query_data['sql']), $query_data['parameters']);

return new Response($this->twig->render('@Pomm/Profiler/explain.html.twig', array(
'token' => $token,
'profile' => $profile,
'collector' => $profile->getCollector($panel),
'panel' => $panel,
'page' => $page,
'request' => $request,
'query_index' => $index_query,
'explain' => $explain,
)), 200, array('Content-Type' => 'text/html'));
}
}
155 changes: 155 additions & 0 deletions sources/lib/DatabaseDataCollector.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
<?php
/*
* This file is part of the PommProject/PommBundle package.
*
* (c) 2018 Grégoire HUBERT <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace PommProject\PommBundle;

use PommProject\Foundation\Exception\SqlException;
use PommProject\Foundation\Listener\Listener;
use PommProject\Foundation\Session\Session;

use Symfony\Component\Stopwatch\Stopwatch;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\DataCollector\DataCollector;

/**
* Data collector for the database profiler.
*
* @package PommBundle
* @copyright 2018 Grégoire HUBERT
* @author Jérôme MACIAS
* @author Grégoire HUBERT
* @license X11 {@link http://opensource.org/licenses/mit-license.php}
* @see DataCollector
*/
class DatabaseDataCollector extends DataCollector
{
/** @var Stopwatch */
private $stopwatch;

public function __construct($unused = null, Stopwatch $stopwatch = null)
{
if ($unused !== null) {
trigger_error("The parameter Pomm has been deleted for to delete the high dependency.", E_USER_DEPRECATED);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe rephrase it to The Pomm parameter has been deleted in order to remove the higher dependency or somethin ?

}

$this->stopwatch = $stopwatch;
$this->data = [
'time' => 0,
'queries' => [],
'exception' => null,
];
}

/**
* @param string $name
* @param array $data
* @param $session

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@param Session $session

*
* @return null

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

void

*/
public function execute($name, $data, Session $session)
{
switch ($name) {
case 'query:post':
$this->data['time'] += $data['time_ms'];
$data += array_pop($this->data['queries']);
/* fall-through */
case 'query:pre':
$this->data['queries'][] = $data;
break;
}

$this->watch($name);
}

private function watch($name)
{
if ($this->stopwatch !== null) {
switch ($name) {
case 'query:pre':
$this->stopwatch->start('query.pomm', 'pomm');
break;
case 'query:post':
$this->stopwatch->stop('query.pomm');
break;
}
}
}

/**
* {@inheritdoc}
*/
public function collect(Request $request, Response $response, \Exception $exception = null)
{
if ($exception instanceof SqlException) {
$this->data['exception'] = $exception->getMessage();
}
}

/**
* Return the list of queries sent.
*
* @return array
*/
public function getQueries()
{
return $this->data['queries'];
}

/**
* Return the number of queries sent.
*
* @return integer
*/
public function getQuerycount()
{
return count($this->data['queries']);
}

/**
* Return queries total time.
*
* @return float
*/
public function getTime()
{
return $this->data['time'];
}

/**
* Return sql exception.
*
* @return \PommProject\Foundation\Exception\SqlException|null
*/
public function getException()
{
return $this->data['exception'];
}

/**
* Return profiler identifier.
*
* @return string
*/
public function getName()
{
return 'pomm';
}

/**
* {@inheritdoc}
*/
public function reset()
{
$this->stopwatch->reset();
$this->data = array();
}
}
2 changes: 1 addition & 1 deletion sources/lib/DependencyInjection/Compiler/ProfilerPass.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ public function process(DI\ContainerBuilder $container)
return;
}

$definition = new DI\Definition("PommProject\\SymfonyBridge\\Controller\\PommProfilerController", [
$definition = new DI\Definition("PommProject\\PommBundle\\Controller\\PommProfilerController", [
new DI\Reference('router'),
new DI\Reference('profiler'),
new DI\Reference('twig'),
Expand Down
64 changes: 64 additions & 0 deletions sources/lib/PropertyInfo/Extractor/ListExtractor.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
<?php
/*
* This file is part of the PommProject/PommBundle package.
*
* (c) 2018 Grégoire HUBERT <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace PommProject\PommBundle\PropertyInfo\Extractor;

use PommProject\Foundation\Pomm;
use PommProject\Foundation\Session;
use Symfony\Component\PropertyInfo\PropertyListExtractorInterface;

/**
* Extract properties list using pomm.
*
* @package PommBundle
* @copyright 2018 Grégoire HUBERT
* @author Nicolas Joseph
* @license X11 {@link http://opensource.org/licenses/mit-license.php}
*/
class ListExtractor implements PropertyListExtractorInterface
{
private $pomm;

public function __construct(Pomm $pomm)
{
$this->pomm = $pomm;
}

/**
* @see PropertyListExtractorInterface
*/
public function getProperties($class, array $context = array())
{
if (isset($context['session:name'])) {
$session = $this->pomm->getSession($context['session:name']);
} else {
$session = $this->pomm->getDefaultSession();
}

if (isset($context['model:name'])) {
$model_name = $context['model:name'];
} else {
$model_name = "${class}Model";

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I prefer the

$model_name = "{$class}Model";

syntax as it allows the use of sub properties or function calls

}

if (!class_exists($model_name)) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might be worth to move it up a bit. As it doesn't require the session to exit.

return;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would add a warning in the logs could be usefull here ?

}

return $this->getPropertiesList($session, $model_name);
}

private function getPropertiesList(Session $session, $model_name)
{
$model = $session->getModel($model_name);
$structure = $model->getStructure();

return $structure->getFieldNames();
}
}
Loading