Skip to content

Commit

Permalink
Merge pull request #89 from moufmouf/4.0
Browse files Browse the repository at this point in the history
Adding logging capabilities
  • Loading branch information
moufmouf committed Apr 28, 2016
2 parents 342c0a3 + 7b464e4 commit fa0ab35
Show file tree
Hide file tree
Showing 7 changed files with 116 additions and 13 deletions.
5 changes: 3 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,12 @@
"doctrine/inflector": "~1.0",
"beberlei/porpaginas": "~1.0",
"mouf/classname-mapper": "~1.0",
"mouf/utils.common.doctrine-cache-wrapper": "~1.0"
"mouf/utils.common.doctrine-cache-wrapper": "~1.0",
"logger/essentials" : "^1.8"
},
"require-dev" : {
"phpunit/phpunit": "~4.0 | ~5.0",
"satooshi/php-coveralls": "dev-master"
"satooshi/php-coveralls": "~1.0"
},
"suggest" : {
"ext/weakref" : "Allows efficient memory management. Useful for batches."
Expand Down
33 changes: 33 additions & 0 deletions doc/miscellaneous.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,3 +79,36 @@ $firstNames = $users->map(function(UserBean $user) {
});
```

Logging and debugging
---------------------

TDBM uses MagicQuery to automatically guess the joins you want. If for some reason, the guess is bad, it can be quite
difficult to understand the request performed.

In these cases, you will want to enable logging.

For this, **you need to pass a [PSR-3](http://www.php-fig.org/psr/psr-3/) compatible logger** as the 4th parameter of the `TDBMService` constructor.

TDBM can log quite a lot so by default, TDBM will restrict itself to only logging "warning" messages (or above).
If you enable logging of "debug" messages, you will see any SELECT request performed by TDBM.

For instance, to log a specific SQL request, you can do:

```php
class UserDao extends UserBaseDao {

/**
* Returns the list of users starting with $firstLetter
*
* @param string $firstLetter
* @return UserBean[]
*/
public function getUsersByLetter($firstLetter) {
$this->tdbmService->setLogLevel(LogLevel::DEBUG);
return $this->find("name LIKE :name", [ "name" => $firstLetter.'%' ]);
$this->tdbmService->setLogLevel(LogLevel::WARNING);
}
}
```

**Do not forget to register a PSR-3 logger in your `TDBMService`, otherwise, nothing will be logged!**
11 changes: 10 additions & 1 deletion src/Mouf/Database/TDBM/InnerResultIterator.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use Doctrine\DBAL\Statement;
use Mouf\Database\MagicQuery;
use Psr\Log\LoggerInterface;

/*
Copyright (C) 2006-2016 David Négrier - THE CODING MACHINE
Expand Down Expand Up @@ -56,7 +57,12 @@ class InnerResultIterator implements \Iterator, \Countable, \ArrayAccess

private $databasePlatform;

public function __construct($magicSql, array $parameters, $limit, $offset, array $columnDescriptors, $objectStorage, $className, TDBMService $tdbmService, MagicQuery $magicQuery)
/**
* @var LoggerInterface
*/
private $logger;

public function __construct($magicSql, array $parameters, $limit, $offset, array $columnDescriptors, $objectStorage, $className, TDBMService $tdbmService, MagicQuery $magicQuery, LoggerInterface $logger)
{
$this->magicSql = $magicSql;
$this->objectStorage = $objectStorage;
Expand All @@ -68,13 +74,16 @@ public function __construct($magicSql, array $parameters, $limit, $offset, array
$this->columnDescriptors = $columnDescriptors;
$this->magicQuery = $magicQuery;
$this->databasePlatform = $this->tdbmService->getConnection()->getDatabasePlatform();
$this->logger = $logger;
}

protected function executeQuery()
{
$sql = $this->magicQuery->build($this->magicSql, $this->parameters);
$sql = $this->tdbmService->getConnection()->getDatabasePlatform()->modifyLimitQuery($sql, $this->limit, $this->offset);

$this->logger->debug('Running SQL request: '.$sql);

$this->statement = $this->tdbmService->getConnection()->executeQuery($sql, $this->parameters);

$this->fetchStarted = true;
Expand Down
13 changes: 10 additions & 3 deletions src/Mouf/Database/TDBM/PageIterator.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use Doctrine\DBAL\Statement;
use Mouf\Database\MagicQuery;
use Porpaginas\Page;
use Psr\Log\LoggerInterface;

/*
Copyright (C) 2006-2016 David Négrier - THE CODING MACHINE
Expand Down Expand Up @@ -62,7 +63,12 @@ class PageIterator implements Page, \ArrayAccess, \JsonSerializable

private $mode;

public function __construct(ResultIterator $parentResult, $magicSql, array $parameters, $limit, $offset, array $columnDescriptors, $objectStorage, $className, TDBMService $tdbmService, MagicQuery $magicQuery, $mode)
/**
* @var LoggerInterface
*/
private $logger;

public function __construct(ResultIterator $parentResult, $magicSql, array $parameters, $limit, $offset, array $columnDescriptors, $objectStorage, $className, TDBMService $tdbmService, MagicQuery $magicQuery, $mode, LoggerInterface $logger)
{
$this->parentResult = $parentResult;
$this->magicSql = $magicSql;
Expand All @@ -76,6 +82,7 @@ public function __construct(ResultIterator $parentResult, $magicSql, array $para
$this->magicQuery = $magicQuery;
$this->databasePlatform = $this->tdbmService->getConnection()->getDatabasePlatform();
$this->mode = $mode;
$this->logger = $logger;
}

/**
Expand All @@ -92,9 +99,9 @@ public function getIterator()
{
if ($this->innerResultIterator === null) {
if ($this->mode === TDBMService::MODE_CURSOR) {
$this->innerResultIterator = new InnerResultIterator($this->magicSql, $this->parameters, $this->limit, $this->offset, $this->columnDescriptors, $this->objectStorage, $this->className, $this->tdbmService, $this->magicQuery);
$this->innerResultIterator = new InnerResultIterator($this->magicSql, $this->parameters, $this->limit, $this->offset, $this->columnDescriptors, $this->objectStorage, $this->className, $this->tdbmService, $this->magicQuery, $this->logger);
} else {
$this->innerResultIterator = new InnerResultArray($this->magicSql, $this->parameters, $this->limit, $this->offset, $this->columnDescriptors, $this->objectStorage, $this->className, $this->tdbmService, $this->magicQuery);
$this->innerResultIterator = new InnerResultArray($this->magicSql, $this->parameters, $this->limit, $this->offset, $this->columnDescriptors, $this->objectStorage, $this->className, $this->tdbmService, $this->magicQuery, $this->logger);
}
}

Expand Down
13 changes: 9 additions & 4 deletions src/Mouf/Database/TDBM/ResultIterator.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use Doctrine\DBAL\Statement;
use Mouf\Database\MagicQuery;
use Porpaginas\Result;
use Psr\Log\LoggerInterface;
use Traversable;

/*
Expand Down Expand Up @@ -66,7 +67,9 @@ class ResultIterator implements Result, \ArrayAccess, \JsonSerializable

private $mode;

public function __construct($magicSql, $magicSqlCount, array $parameters, array $columnDescriptors, $objectStorage, $className, TDBMService $tdbmService, MagicQuery $magicQuery, $mode)
private $logger;

public function __construct($magicSql, $magicSqlCount, array $parameters, array $columnDescriptors, $objectStorage, $className, TDBMService $tdbmService, MagicQuery $magicQuery, $mode, LoggerInterface $logger)
{
$this->magicSql = $magicSql;
$this->magicSqlCount = $magicSqlCount;
Expand All @@ -78,11 +81,13 @@ public function __construct($magicSql, $magicSqlCount, array $parameters, array
$this->magicQuery = $magicQuery;
$this->databasePlatform = $this->tdbmService->getConnection()->getDatabasePlatform();
$this->mode = $mode;
$this->logger = $logger;
}

protected function executeCountQuery()
{
$sql = $this->magicQuery->build($this->magicSqlCount, $this->parameters);
$this->logger->debug("Running count query: ".$sql);
$this->totalCount = $this->tdbmService->getConnection()->fetchColumn($sql, $this->parameters);
}

Expand Down Expand Up @@ -136,9 +141,9 @@ public function getIterator()
{
if ($this->innerResultIterator === null) {
if ($this->mode === TDBMService::MODE_CURSOR) {
$this->innerResultIterator = new InnerResultIterator($this->magicSql, $this->parameters, null, null, $this->columnDescriptors, $this->objectStorage, $this->className, $this->tdbmService, $this->magicQuery);
$this->innerResultIterator = new InnerResultIterator($this->magicSql, $this->parameters, null, null, $this->columnDescriptors, $this->objectStorage, $this->className, $this->tdbmService, $this->magicQuery, $this->logger);
} else {
$this->innerResultIterator = new InnerResultArray($this->magicSql, $this->parameters, null, null, $this->columnDescriptors, $this->objectStorage, $this->className, $this->tdbmService, $this->magicQuery);
$this->innerResultIterator = new InnerResultArray($this->magicSql, $this->parameters, null, null, $this->columnDescriptors, $this->objectStorage, $this->className, $this->tdbmService, $this->magicQuery, $this->logger);
}
}

Expand All @@ -152,7 +157,7 @@ public function getIterator()
*/
public function take($offset, $limit)
{
return new PageIterator($this, $this->magicSql, $this->parameters, $limit, $offset, $this->columnDescriptors, $this->objectStorage, $this->className, $this->tdbmService, $this->magicQuery, $this->mode);
return new PageIterator($this, $this->magicSql, $this->parameters, $limit, $offset, $this->columnDescriptors, $this->objectStorage, $this->className, $this->tdbmService, $this->magicQuery, $this->mode, $this->logger);
}

/**
Expand Down
40 changes: 37 additions & 3 deletions src/Mouf/Database/TDBM/TDBMService.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,13 @@
use Doctrine\DBAL\Schema\Schema;
use Doctrine\DBAL\Schema\Table;
use Doctrine\DBAL\Types\Type;
use Logger\Filters\MinLogLevelFilter;
use Mouf\Database\MagicQuery;
use Mouf\Database\SchemaAnalyzer\SchemaAnalyzer;
use Mouf\Database\TDBM\Utils\TDBMDaoGenerator;
use Psr\Log\LoggerInterface;
use Psr\Log\LogLevel;
use Psr\Log\NullLogger;

/**
* The TDBMService class is the main TDBM class. It provides methods to retrieve TDBMObject instances
Expand Down Expand Up @@ -129,13 +133,23 @@ class TDBMService
*/
private $reflectionClassCache = array();

/**
* @var LoggerInterface
*/
private $rootLogger;

/**
* @var MinLogLevelFilter|NullLogger
*/
private $logger;

/**
* @param Connection $connection The DBAL DB connection to use
* @param Cache|null $cache A cache service to be used
* @param SchemaAnalyzer $schemaAnalyzer The schema analyzer that will be used to find shortest paths...
* Will be automatically created if not passed.
*/
public function __construct(Connection $connection, Cache $cache = null, SchemaAnalyzer $schemaAnalyzer = null)
public function __construct(Connection $connection, Cache $cache = null, SchemaAnalyzer $schemaAnalyzer = null, LoggerInterface $logger = null)
{
if (extension_loaded('weakref')) {
$this->objectStorage = new WeakrefObjectStorage();
Expand All @@ -160,6 +174,13 @@ public function __construct(Connection $connection, Cache $cache = null, SchemaA
$this->cachePrefix = $this->tdbmSchemaAnalyzer->getCachePrefix();

$this->toSaveObjects = new \SplObjectStorage();
if ($logger === null) {
$this->logger = new NullLogger();
$this->rootLogger = new NullLogger();
} else {
$this->rootLogger = $logger;
$this->setLogLevel(LogLevel::WARNING);
}
}

/**
Expand Down Expand Up @@ -1306,7 +1327,7 @@ public function findObjects($mainTable, $filter = null, array $parameters = arra

$mode = $mode ?: $this->mode;

return new ResultIterator($sql, $countSql, $parameters, $columnDescList, $this->objectStorage, $className, $this, $this->magicQuery, $mode);
return new ResultIterator($sql, $countSql, $parameters, $columnDescList, $this->objectStorage, $className, $this, $this->magicQuery, $mode, $this->logger);
}

/**
Expand Down Expand Up @@ -1410,7 +1431,7 @@ public function findObjectsFromSql($mainTable, $from, $filter = null, array $par

$mode = $mode ?: $this->mode;

return new ResultIterator($sql, $countSql, $parameters, $columnDescList, $this->objectStorage, $className, $this, $this->magicQuery, $mode);
return new ResultIterator($sql, $countSql, $parameters, $columnDescList, $this->objectStorage, $className, $this, $this->magicQuery, $mode, $this->logger);
}

/**
Expand Down Expand Up @@ -1769,4 +1790,17 @@ public function _getColumnTypesForTable($tableName)

return $typesForTable[$tableName];
}

/**
* Sets the minimum log level.
* $level must be one of Psr\Log\LogLevel::xxx
*
* Defaults to LogLevel::WARNING
*
* @param $level
*/
public function setLogLevel($level)
{
$this->logger = new MinLogLevelFilter($this->rootLogger, $level);
}
}
14 changes: 14 additions & 0 deletions tests/Mouf/Database/TDBM/TDBMServiceTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,10 @@

namespace Mouf\Database\TDBM;

use Logger\Loggers\ArrayLogger;
use Mouf\Database\TDBM\Filters\EqualFilter;
use Mouf\Database\TDBM\Filters\OrderByColumn;
use Psr\Log\LogLevel;

/**
*/
Expand Down Expand Up @@ -631,6 +633,18 @@ public function testFindObjectsFromSqlHierarchyUp()
$this->assertSame('Robert Marley', $users[0]->getProperty('name', 'person'));
}

public function testLogger()
{

$arrayLogger = new ArrayLogger();
$tdbmService = new TDBMService($this->dbConnection, null, null, $arrayLogger);

$tdbmService->setLogLevel(LogLevel::DEBUG);
$beans = $tdbmService->findObjects('contact', null, [], 'contact.id ASC');

$this->assertNotEmpty($arrayLogger);
}

/*
public function testObjectAsFilter() {
$dpt = $this->tdbmService->getObject('departements', 1);
Expand Down

0 comments on commit fa0ab35

Please sign in to comment.