class ApdqcFakeDatabaseStatement in Asynchronous Prefetch Database Query Cache 7
Fake database statement class for devel logging.
Hierarchy
- class \DatabaseStatementEmpty implements \Iterator, DatabaseStatementInterface
- class \ApdqcFakeDatabaseStatement
Expanded class hierarchy of ApdqcFakeDatabaseStatement
File
- ./
apdqc.log.inc, line 10 - Creates a fake db statement for devel query logging.
View source
class ApdqcFakeDatabaseStatement extends DatabaseStatementEmpty {
public $dbh;
public $queryString;
/**
* Constructs a DrupalDatabaseCache object.
*
* @param string $query_string
* The query string.
* @param string $extra_data
* Extra data about the query; cache hit/miss, etc.
*/
public function __construct($query_string, $extra_data = '') {
$dbh = new ApdqcFakeDbh();
$this->dbh = $dbh;
$timestamp = '';
if (!empty($_SERVER['REQUEST_TIME_FLOAT'])) {
$timestamp = ' at ' . round(microtime(TRUE) - $_SERVER['REQUEST_TIME_FLOAT'], 5) * 1000 . 'ms';
}
$query_string = '/* ' . $extra_data . $this
->findCallerfunction() . $timestamp . ' */ ' . $query_string;
$this->queryString = $query_string;
}
/**
* Gets the query string of this statement.
*
* @return string
* The query string, in its form with placeholders.
*/
public function getQueryString() {
return $this->queryString;
}
/**
* 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 includes/database 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. Also makes sure this is not from the
* cache api.
*
* @link http://www.php.net/debug_backtrace
*
* @return string
* 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 findCallerfunction() {
$stack = debug_backtrace();
$stack_count = count($stack);
for ($i = 0; $i < $stack_count; ++$i) {
if (!empty($stack[$i]['file']) && strpos($stack[$i]['file'], 'includes' . DIRECTORY_SEPARATOR . 'database') === FALSE && strpos($stack[$i]['file'], 'includes' . DIRECTORY_SEPARATOR . 'cache') === FALSE && strpos($stack[$i]['file'], 'apdqc.cache.inc') === FALSE && strpos($stack[$i]['function'], '__construct') === FALSE && strpos($stack[$i + 1]['function'], '__construct') === FALSE && strpos($stack[$i]['function'], __FUNCTION__) === FALSE && strpos($stack[$i + 1]['function'], 'apdqc_get_db_object') === FALSE) {
$stack[$i] += array(
'args' => array(),
);
$full_stack = array();
if (variable_get('apdqc_verbose_devel_output', APDQC_VERBOSE_DEVEL_OUTPUT)) {
foreach ($stack as $trace) {
if (!isset($trace['args'])) {
$trace['args'] = 1;
}
if (isset($trace['class'])) {
$full_stack[] = $trace['class'] . '::' . $trace['function'] . '(' . count($trace['args']) . ')';
}
else {
$full_stack[] = $trace['function'] . '(' . count($trace['args']) . ')';
}
}
$full_stack = array_slice($full_stack, 2, 30);
}
return 'Call from ' . $stack[$i + 1]['function'] . '()' . '. ' . implode(' -> ', array_reverse($full_stack));
}
}
}
}