Code Coverage |
||||||||||
Classes and Traits |
Functions and Methods |
Lines |
||||||||
| Total | |
0.00% |
0 / 1 |
|
0.00% |
0 / 7 |
CRAP | |
0.00% |
0 / 31 |
| Log | |
0.00% |
0 / 1 |
|
0.00% |
0 / 7 |
272 | |
0.00% |
0 / 31 |
| __construct | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 2 |
|||
| start | |
0.00% |
0 / 1 |
6 | |
0.00% |
0 / 3 |
|||
| get | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 1 |
|||
| clear | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 2 |
|||
| end | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 2 |
|||
| log | |
0.00% |
0 / 1 |
6 | |
0.00% |
0 / 8 |
|||
| findCaller | |
0.00% |
0 / 1 |
72 | |
0.00% |
0 / 13 |
|||
| <?php | |
| /** | |
| * @file | |
| * Contains \Drupal\Core\Database\Log. | |
| */ | |
| namespace Drupal\Core\Database; | |
| /** | |
| * Database query logger. | |
| * | |
| * We log queries in a separate object rather than in the connection object | |
| * because we want to be able to see all queries sent to a given database, not | |
| * database target. If we logged the queries in each connection object we | |
| * would not be able to track what queries went to which target. | |
| * | |
| * Every connection has one and only one logging object on it for all targets | |
| * and logging keys. | |
| */ | |
| class Log { | |
| /** | |
| * Cache of logged queries. This will only be used if the query logger is enabled. | |
| * | |
| * The structure for the logging array is as follows: | |
| * | |
| * array( | |
| * $logging_key = array( | |
| * array(query => '', args => array(), caller => '', target => '', time => 0), | |
| * array(query => '', args => array(), caller => '', target => '', time => 0), | |
| * ), | |
| * ); | |
| * | |
| * @var array | |
| */ | |
| protected $queryLog = array(); | |
| /** | |
| * The connection key for which this object is logging. | |
| * | |
| * @var string | |
| */ | |
| protected $connectionKey = 'default'; | |
| /** | |
| * Constructor. | |
| * | |
| * @param $key | |
| * The database connection key for which to enable logging. | |
| */ | |
| public function __construct($key = 'default') { | |
| $this->connectionKey = $key; | |
| } | |
| /** | |
| * Begin logging queries to the specified connection and logging key. | |
| * | |
| * If the specified logging key is already running this method does nothing. | |
| * | |
| * @param $logging_key | |
| * The identification key for this log request. By specifying different | |
| * logging keys we are able to start and stop multiple logging runs | |
| * simultaneously without them colliding. | |
| */ | |
| public function start($logging_key) { | |
| if (empty($this->queryLog[$logging_key])) { | |
| $this->clear($logging_key); | |
| } | |
| } | |
| /** | |
| * Retrieve the query log for the specified logging key so far. | |
| * | |
| * @param $logging_key | |
| * The logging key to fetch. | |
| * @return | |
| * An indexed array of all query records for this logging key. | |
| */ | |
| public function get($logging_key) { | |
| return $this->queryLog[$logging_key]; | |
| } | |
| /** | |
| * Empty the query log for the specified logging key. | |
| * | |
| * This method does not stop logging, it simply clears the log. To stop | |
| * logging, use the end() method. | |
| * | |
| * @param $logging_key | |
| * The logging key to empty. | |
| */ | |
| public function clear($logging_key) { | |
| $this->queryLog[$logging_key] = array(); | |
| } | |
| /** | |
| * Stop logging for the specified logging key. | |
| * | |
| * @param $logging_key | |
| * The logging key to stop. | |
| */ | |
| public function end($logging_key) { | |
| unset($this->queryLog[$logging_key]); | |
| } | |
| /** | |
| * Log a query to all active logging keys. | |
| * | |
| * @param $statement | |
| * The prepared statement object to log. | |
| * @param $args | |
| * The arguments passed to the statement object. | |
| * @param $time | |
| * The time in milliseconds the query took to execute. | |
| */ | |
| public function log(StatementInterface $statement, $args, $time) { | |
| foreach (array_keys($this->queryLog) as $key) { | |
| $this->queryLog[$key][] = array( | |
| 'query' => $statement->getQueryString(), | |
| 'args' => $args, | |
| 'target' => $statement->dbh->getTarget(), | |
| 'caller' => $this->findCaller(), | |
| 'time' => $time, | |
| ); | |
| } | |
| } | |
| /** | |
| * Determine the routine that called this query. | |
| * | |
| * We define "the routine that called this query" as the first entry in | |
| * the call stack that is not inside the includes/Drupal/Database directory, | |
| * does not begin with db_ and does have a file (which excludes | |
| * call_user_func_array(), anonymous functions and similar). That makes the | |
| * climbing logic very simple, and handles the variable stack depth caused by | |
| * the query builders. | |
| * | |
| * @link http://www.php.net/debug_backtrace | |
| * @return | |
| * This method returns a stack trace entry similar to that generated by | |
| * debug_backtrace(). However, it flattens the trace entry and the trace | |
| * entry before it so that we get the function and args of the function that | |
| * called into the database system, not the function and args of the | |
| * database call itself. | |
| */ | |
| public function findCaller() { | |
| $stack = debug_backtrace(); | |
| for ($i = 0, $stack_count = count($stack); $i < $stack_count; ++$i) { | |
| // If the call was made from a function, 'class' will be empty. It's | |
| // just easier to give it a default value than to try and integrate | |
| // that into the if statement below. | |
| if (empty($stack[$i]['class'])) { | |
| $stack[$i]['class'] = ''; | |
| } | |
| if (strpos($stack[$i]['class'], __NAMESPACE__) === FALSE && strpos($stack[$i + 1]['function'], 'db_') === FALSE && !empty($stack[$i]['file'])) { | |
| $stack[$i] += array('file' => '?', 'line' => '?', 'args' => array()); | |
| return array( | |
| 'file' => $stack[$i]['file'], | |
| 'line' => $stack[$i]['line'], | |
| 'function' => $stack[$i + 1]['function'], | |
| 'class' => isset($stack[$i + 1]['class']) ? $stack[$i + 1]['class'] : NULL, | |
| 'type' => isset($stack[$i + 1]['type']) ? $stack[$i + 1]['type'] : NULL, | |
| 'args' => $stack[$i + 1]['args'], | |
| ); | |
| } | |
| } | |
| } | |
| } |