/** * Outputs some debug information about queries run during the current request. * * @param integer|string $limit Either an integer to return the last many queries, a regular expression or a substring to search for */ public function debug($limit = null) { if (!($databaseManager = $this->browser->getContext()->getDatabaseManager())) { throw new LogicConnection('The current context does not include a database manager.'); } $events = array(); foreach ($databaseManager->getNames() as $name) { $database = $databaseManager->getDatabase($name); if ($database instanceof sfDoctrineDatabase && ($profiler = $database->getProfiler())) { foreach ($profiler->getQueryExecutionEvents() as $event) { $events[$event->getSequence()] = $event; } } } // sequence events ksort($events); if (is_integer($limit)) { $events = array_slice($events, $limit * -1); } else { if (preg_match('/^(!)?([^a-zA-Z0-9\\\\]).+?\\2[ims]?$/', $limit, $match)) { if ($match[1] == '!') { $pattern = substr($limit, 1); $match = false; } else { $pattern = $limit; $match = true; } } else { if ($limit) { $substring = $limit; } } } echo "\nDumping SQL executed in the current context:\n\n"; foreach ($events as $event) { if (!isset($pattern) && !isset($substring) || isset($pattern) && $match == preg_match($pattern, $event->getQuery()) || isset($substring) && false !== stripos($event->getQuery(), $substring)) { $conn = $event->getInvoker() instanceof Doctrine_Connection ? $event->getInvoker() : $event->getInvoker()->getConnection(); echo $event->getQuery() . "\n"; echo ' Parameters: ' . sfYaml::dump(sfDoctrineConnectionProfiler::fixParams($event->getParams()), 0) . "\n"; echo ' Connection: ' . $conn->getName() . "\n"; echo ' Time: ' . number_format($event->getElapsedSecs(), 2) . "s\n\n"; } } exit(1); }
/** * Builds the sql logs and returns them as an array. * * @return array */ protected function getSqlLogs() { $logs = $this->webDebug->getLogger()->getLogs(); $html = array(); foreach ($this->getDoctrineEvents() as $i => $event) { $conn = $event->getInvoker() instanceof Doctrine_Connection ? $event->getInvoker() : $event->getInvoker()->getConnection(); $params = sfDoctrineConnectionProfiler::fixParams($event->getParams()); $query = $this->formatSql(htmlspecialchars($event->getQuery(), ENT_QUOTES, sfConfig::get('sf_charset'))); // interpolate parameters foreach ($params as $param) { $param = htmlspecialchars($param, ENT_QUOTES, sfConfig::get('sf_charset')); $query = join(var_export(is_scalar($param) ? $param : (string) $param, true), explode('?', $query, 2)); } // slow query if ($event->slowQuery && $this->getStatus() > sfLogger::NOTICE) { $this->setStatus(sfLogger::NOTICE); } // backtrace $backtrace = null; foreach ($logs as $i => $log) { if (!isset($log['debug_backtrace']) || !count($log['debug_backtrace'])) { // backtrace disabled break; } if (false !== strpos($log['message'], $event->getQuery())) { // assume queries are being requested in order unset($logs[$i]); $backtrace = ' '.$this->getToggleableDebugStack($log['debug_backtrace']); break; } } $html[] = sprintf(' <li%s> <p class="sfWebDebugDatabaseQuery">%s</p> <div class="sfWebDebugDatabaseLogInfo">%ss, "%s" connection%s</div> </li>', $event->slowQuery ? ' class="sfWebDebugWarning"' : '', $query, number_format($event->getElapsedSecs(), 2), $conn->getName(), $backtrace ); } return $html; }