diff --git a/dibi/Nette/DibiNettePanel.php b/dibi/Nette/DibiNettePanel.php new file mode 100644 index 00000000..70167504 --- /dev/null +++ b/dibi/Nette/DibiNettePanel.php @@ -0,0 +1,164 @@ +filter = $filter ? (int) $filter : DibiEvent::QUERY; + $this->explain = (bool) $explain; + } + + + + public function register(DibiConnection $connection) + { + if (is_callable('Nette\Diagnostics\Debugger::enable')) { + class_alias('Nette\Diagnostics\Debugger', 'NDebugger'); // PHP 5.2 code compatibility + } + if (is_callable('NDebugger::enable')) { + NDebugger::$bar->addPanel($this); + NDebugger::$blueScreen->addPanel(array($this, 'renderException'), __CLASS__); + $connection->onEvent[] = array($this, 'logEvent'); + } elseif (is_callable('Debugger::enable')) { + Debugger::$bar->addPanel($this); + Debugger::$blueScreen->addPanel(array($this, 'renderException'), __CLASS__); + $connection->onEvent[] = array($this, 'logEvent'); + } + } + + + + /** + * After event notification. + * @return void + */ + public function logEvent(DibiEvent $event) + { + if (($event->type & $this->filter) === 0) { + return; + } + $this->events[] = $event; + } + + + + /** + * Returns blue-screen custom tab. + * @return mixed + */ + public function renderException($e) + { + if ($e instanceof DibiException && $e->getSql()) { + return array( + 'tab' => 'SQL', + 'panel' => dibi::dump($e->getSql(), TRUE), + ); + } + } + + + + /** + * Returns HTML code for custom tab. (Nette\Diagnostics\IBarPanel) + * @return mixed + */ + public function getTab() + { + return '' + . dibi::$numOfQueries . ' queries' + . (dibi::$totalTime ? ' / ' . sprintf('%0.1f', dibi::$totalTime * 1000) . 'ms' : '') + . ''; + } + + + + /** + * Returns HTML code for custom panel. (Nette\Diagnostics\IBarPanel) + * @return mixed + */ + public function getPanel() + { + $s = NULL; + $h = 'htmlSpecialChars'; + foreach ($this->events as $event) { + $explain = NULL; // EXPLAIN is called here to work SELECT FOUND_ROWS() + if ($this->explain && $event->type === DibiEvent::SELECT) { + try { + $backup = array($event->connection->onEvent, dibi::$numOfQueries, dibi::$totalTime); + $event->connection->onEvent = NULL; + $explain = dibi::dump($event->connection->nativeQuery('EXPLAIN ' . $event->sql), TRUE); + } catch (DibiException $e) {} + list($event->connection->onEvent, dibi::$numOfQueries, dibi::$totalTime) = $backup; + } + + $s .= '' . sprintf('%0.3f', $event->time * 1000); + if ($explain) { + static $counter; + $counter++; + $s .= "
explain ►"; + } + + $s .= '' . dibi::dump(strlen($event->sql) > self::$maxLength ? substr($event->sql, 0, self::$maxLength) . '...' : $event->sql, TRUE); + if ($explain) { + $s .= "
{$explain}
"; + } + if ($event->source) { + $helpers = 'Nette\Diagnostics\Helpers'; + if (!class_exists($helpers)) { + $helpers = class_exists('NDebugHelpers') ? 'NDebugHelpers' : 'DebugHelpers'; + } + $s .= call_user_func(array($helpers, 'editorLink'), $event->source[0], $event->source[1])->class('nette-DibiProfiler-source'); + } + + $s .= "{$event->count}{$h($event->connection->getConfig('driver') . '/' . $event->connection->getConfig('name'))}"; + } + + return empty($this->events) ? '' : + ' +

Queries: ' . dibi::$numOfQueries . (dibi::$totalTime === NULL ? '' : ', time: ' . sprintf('%0.3f', dibi::$totalTime * 1000) . ' ms') . '

+
+ + ' . $s . ' +
Time msSQL StatementRowsConnection
+
'; + } + +} diff --git a/dibi/dibi.php b/dibi/dibi.php index 11440bf6..4f5f2dea 100644 --- a/dibi/dibi.php +++ b/dibi/dibi.php @@ -23,18 +23,6 @@ if (version_compare(PHP_VERSION, '5.2.0', '<')) { -/** - * Compatibility with Nette - */ -if (interface_exists('Nette\Diagnostics\IBarPanel')) { - class_alias('Nette\Diagnostics\IBarPanel', 'IBarPanel'); - -} elseif (!interface_exists('IBarPanel')) { - interface IBarPanel {} -} - - - require_once dirname(__FILE__) . '/libs/interfaces.php'; require_once dirname(__FILE__) . '/libs/DibiDateTime.php'; require_once dirname(__FILE__) . '/libs/DibiObject.php'; @@ -48,7 +36,10 @@ require_once dirname(__FILE__) . '/libs/DibiTranslator.php'; require_once dirname(__FILE__) . '/libs/DibiDataSource.php'; require_once dirname(__FILE__) . '/libs/DibiFluent.php'; require_once dirname(__FILE__) . '/libs/DibiDatabaseInfo.php'; -require_once dirname(__FILE__) . '/libs/DibiProfiler.php'; +require_once dirname(__FILE__) . '/libs/DibiEvent.php'; +require_once dirname(__FILE__) . '/libs/DibiFileLogger.php'; +require_once dirname(__FILE__) . '/libs/DibiFirePhpLogger.php'; +require_once dirname(__FILE__) . '/Nette/DibiNettePanel.php'; @@ -234,18 +225,6 @@ class dibi - /** - * Retrieve active connection profiler. - * @return IDibiProfiler - * @throws DibiException - */ - public static function getProfiler() - { - return self::getConnection()->getProfiler(); - } - - - /********************* monostate for active connection ****************d*g**/ diff --git a/dibi/libs/DibiConnection.php b/dibi/libs/DibiConnection.php index d0422e08..74b956c1 100644 --- a/dibi/libs/DibiConnection.php +++ b/dibi/libs/DibiConnection.php @@ -23,11 +23,13 @@ * @property-read IDibiDriver $driver * @property-read int $affectedRows * @property-read int $insertId - * @property IDibiProfiler $profiler * @property-read DibiDatabaseInfo $databaseInfo */ class DibiConnection extends DibiObject { + /** @var array of function(DibiEvent $event); Occurs after query is executed */ + public $onEvent; + /** @var array Current connection configuration */ private $config; @@ -37,9 +39,6 @@ class DibiConnection extends DibiObject /** @var DibiTranslator */ private $translator; - /** @var IDibiProfiler */ - private $profiler; - /** @var bool Is connected? */ private $connected = FALSE; @@ -56,7 +55,7 @@ class DibiConnection extends DibiObject * - formatDateTime => date-time format (if empty, DateTime objects will be returned) * - profiler (array or bool) * - run (bool) => enable profiler? - * - class => profiler class name (default is DibiProfiler) + * - file => file to log * - substitutes (array) => map of driver specific substitutes (under development) * @param mixed connection parameters @@ -107,20 +106,22 @@ class DibiConnection extends DibiObject // profiler $profilerCfg = & $config['profiler']; - if (is_scalar($profilerCfg)) { // back compatibility - $profilerCfg = array( - 'run' => (bool) $profilerCfg, - 'class' => strlen($profilerCfg) > 1 ? $profilerCfg : NULL, - ); + if (is_scalar($profilerCfg)) { + $profilerCfg = array('run' => (bool) $profilerCfg); } - if (!empty($profilerCfg['run'])) { - class_exists('dibi'); // ensure dibi.php is processed - $class = isset($profilerCfg['class']) ? $profilerCfg['class'] : 'DibiProfiler'; - if (!class_exists($class)) { - throw new DibiException("Unable to create instance of dibi profiler '$class'."); + $filter = isset($profilerCfg['filter']) ? $profilerCfg['filter'] : DibiEvent::QUERY; + + if (isset($profilerCfg['file'])) { + $this->onEvent[] = array(new DibiFileLogger($profilerCfg['file'], $filter), 'logEvent'); } - $this->setProfiler(new $class($profilerCfg)); + + if (DibiFirePhpLogger::isAvailable()) { + $this->onEvent[] = array(new DibiFirePhpLogger($filter), 'logEvent'); + } + + $panel = new DibiNettePanel(isset($profilerCfg['explain']) ? $profilerCfg['explain'] : TRUE, $filter); + $panel->register($this); } $this->substitutes = new DibiHashMap(create_function('$expr', 'return ":$expr:";')); @@ -155,13 +156,15 @@ class DibiConnection extends DibiObject */ final public function connect() { - if ($this->profiler !== NULL) { - $ticket = $this->profiler->before($this, IDibiProfiler::CONNECT); - } - $this->driver->connect($this->config); - $this->connected = TRUE; - if (isset($ticket)) { - $this->profiler->after($ticket); + $event = $this->onEvent ? new DibiEvent($this, DibiEvent::CONNECT) : NULL; + try { + $this->driver->connect($this->config); + $this->connected = TRUE; + $event && $this->onEvent($event->done()); + + } catch (DibiException $e) { + $event && $this->onEvent($event->done($e)); + throw $e; } } @@ -329,28 +332,24 @@ class DibiConnection extends DibiObject { $this->connected || $this->connect(); - if ($this->profiler !== NULL) { - $event = IDibiProfiler::QUERY; - if (preg_match('#\s*(SELECT|UPDATE|INSERT|DELETE)#iA', $sql, $matches)) { - static $events = array( - 'SELECT' => IDibiProfiler::SELECT, 'UPDATE' => IDibiProfiler::UPDATE, - 'INSERT' => IDibiProfiler::INSERT, 'DELETE' => IDibiProfiler::DELETE, - ); - $event = $events[strtoupper($matches[1])]; - } - $ticket = $this->profiler->before($this, $event, $sql); + $event = $this->onEvent ? new DibiEvent($this, DibiEvent::QUERY, $sql) : NULL; + dibi::$numOfQueries++; + dibi::$sql = $sql; + try { + $res = $this->driver->query($sql); + + } catch (DibiException $e) { + $event && $this->onEvent($event->done($e)); + throw $e; } - dibi::$sql = $sql; - if ($res = $this->driver->query($sql)) { // intentionally = + if ($res) { $res = $this->createResultSet($res); } else { $res = $this->driver->getAffectedRows(); } - if (isset($ticket)) { - $this->profiler->after($ticket, $res); - } + $event && $this->onEvent($event->done($res)); return $res; } @@ -420,12 +419,14 @@ class DibiConnection extends DibiObject public function begin($savepoint = NULL) { $this->connected || $this->connect(); - if ($this->profiler !== NULL) { - $ticket = $this->profiler->before($this, IDibiProfiler::BEGIN, $savepoint); - } - $this->driver->begin($savepoint); - if (isset($ticket)) { - $this->profiler->after($ticket); + $event = $this->onEvent ? new DibiEvent($this, DibiEvent::BEGIN, $savepoint) : NULL; + try { + $this->driver->begin($savepoint); + $event && $this->onEvent($event->done()); + + } catch (DibiException $e) { + $event && $this->onEvent($event->done($e)); + throw $e; } } @@ -439,12 +440,14 @@ class DibiConnection extends DibiObject public function commit($savepoint = NULL) { $this->connected || $this->connect(); - if ($this->profiler !== NULL) { - $ticket = $this->profiler->before($this, IDibiProfiler::COMMIT, $savepoint); - } - $this->driver->commit($savepoint); - if (isset($ticket)) { - $this->profiler->after($ticket); + $event = $this->onEvent ? new DibiEvent($this, DibiEvent::COMMIT, $savepoint) : NULL; + try { + $this->driver->commit($savepoint); + $event && $this->onEvent($event->done()); + + } catch (DibiException $e) { + $event && $this->onEvent($event->done($e)); + throw $e; } } @@ -458,12 +461,14 @@ class DibiConnection extends DibiObject public function rollback($savepoint = NULL) { $this->connected || $this->connect(); - if ($this->profiler !== NULL) { - $ticket = $this->profiler->before($this, IDibiProfiler::ROLLBACK, $savepoint); - } - $this->driver->rollback($savepoint); - if (isset($ticket)) { - $this->profiler->after($ticket); + $event = $this->onEvent ? new DibiEvent($this, DibiEvent::ROLLBACK, $savepoint) : NULL; + try { + $this->driver->rollback($savepoint); + $event && $this->onEvent($event->done()); + + } catch (DibiException $e) { + $event && $this->onEvent($event->done($e)); + throw $e; } } @@ -551,32 +556,6 @@ class DibiConnection extends DibiObject - /********************* profiler ****************d*g**/ - - - - /** - * @param IDibiProfiler - * @return DibiConnection provides a fluent interface - */ - public function setProfiler(IDibiProfiler $profiler = NULL) - { - $this->profiler = $profiler; - return $this; - } - - - - /** - * @return IDibiProfiler - */ - public function getProfiler() - { - return $this->profiler; - } - - - /********************* substitutions ****************d*g**/ diff --git a/dibi/libs/DibiEvent.php b/dibi/libs/DibiEvent.php new file mode 100644 index 00000000..58678951 --- /dev/null +++ b/dibi/libs/DibiEvent.php @@ -0,0 +1,103 @@ +connection = $connection; + $this->type = $type; + $this->sql = trim($sql); + $this->time = -microtime(TRUE); + + if ($type === self::QUERY && preg_match('#(SELECT|UPDATE|INSERT|DELETE)#iA', $this->sql, $matches)) { + static $types = array( + 'SELECT' => self::SELECT, 'UPDATE' => self::UPDATE, + 'INSERT' => self::INSERT, 'DELETE' => self::DELETE, + ); + $this->type = $types[strtoupper($matches[1])]; + } + + $rc = new ReflectionClass('dibi'); + $dibiDir = dirname($rc->getFileName()) . DIRECTORY_SEPARATOR; + foreach (debug_backtrace(FALSE) as $row) { + if (isset($row['file']) && is_file($row['file']) && strpos($row['file'], $dibiDir) !== 0) { + $this->source = array($row['file'], (int) $row['line']); + break; + } + } + + dibi::$elapsedTime = FALSE; + } + + + + public function done($result = NULL) + { + $this->result = $result; + try { + $this->count = $result instanceof DibiResult ? count($result) : NULL; + } catch (DibiException $e) { + $this->count = NULL; + } + + $this->time += microtime(TRUE); + dibi::$elapsedTime = $this->time; + dibi::$totalTime += $this->time; + return $this; + } + +} diff --git a/dibi/libs/DibiException.php b/dibi/libs/DibiException.php index 8ee90e44..dd478def 100644 --- a/dibi/libs/DibiException.php +++ b/dibi/libs/DibiException.php @@ -42,7 +42,6 @@ class DibiException extends Exception { parent::__construct($message, (int) $code); $this->sql = $sql; - // TODO: add $profiler->exception($this); } diff --git a/dibi/libs/DibiFileLogger.php b/dibi/libs/DibiFileLogger.php new file mode 100644 index 00000000..a3acc908 --- /dev/null +++ b/dibi/libs/DibiFileLogger.php @@ -0,0 +1,79 @@ +file = $file; + $this->filter = $filter ? (int) $filter : DibiEvent::QUERY; + } + + + + /** + * After event notification. + * @return void + */ + public function logEvent(DibiEvent $event) + { + if (($event->type & $this->filter) === 0) { + return; + } + + $handle = fopen($this->file, 'a'); + if (!$handle) return; // or throw exception? + flock($handle, LOCK_EX); + + if ($event->result instanceof Exception) { + $message = $event->result->getMessage(); + if ($code = $event->result->getCode()) { + $message = "[$code] $message"; + } + fwrite($handle, + "ERROR: $message" + . "\n-- SQL: " . $event->sql + . "\n-- driver: " . $event->connection->getConfig('driver') . '/' . $event->connection->getConfig('name') + . ";\n-- " . date('Y-m-d H:i:s') + . "\n\n" + ); + } else { + fwrite($handle, + "OK: " . $event->sql + . ($event->count ? ";\n-- rows: " . $event->count : '') + . "\n-- takes: " . sprintf('%0.3f', $event->time * 1000) . ' ms' + . "\n-- source: " . implode(':', $event->source) + . "\n-- driver: " . $event->connection->getConfig('driver') . '/' . $event->connection->getConfig('name') + . "\n-- " . date('Y-m-d H:i:s') + . "\n\n" + ); + } + fclose($handle); + } + +} diff --git a/dibi/libs/DibiFirePhpLogger.php b/dibi/libs/DibiFirePhpLogger.php new file mode 100644 index 00000000..52549e4a --- /dev/null +++ b/dibi/libs/DibiFirePhpLogger.php @@ -0,0 +1,89 @@ +filter = $filter ? (int) $filter : DibiEvent::QUERY; + } + + + + /** + * After event notification. + * @return void + */ + public function logEvent(DibiEvent $event) + { + if (headers_sent() || ($event->type & $this->filter) === 0 || count(self::$fireTable) > self::$maxQueries) { + return; + } + + self::$fireTable[] = array( + sprintf('%0.3f', $event->time * 1000), + strlen($event->sql) > self::$maxLength ? substr($event->sql, 0, self::$maxLength) . '...' : $event->sql, + $event->result instanceof Exception ? 'ERROR' : $event->count, + $event->connection->getConfig('driver') . '/' . $event->connection->getConfig('name') + ); + + header('X-Wf-Protocol-dibi: http://meta.wildfirehq.org/Protocol/JsonStream/0.2'); + header('X-Wf-dibi-Plugin-1: http://meta.firephp.org/Wildfire/Plugin/FirePHP/Library-FirePHPCore/0.2.0'); + header('X-Wf-dibi-Structure-1: http://meta.firephp.org/Wildfire/Structure/FirePHP/FirebugConsole/0.1'); + + $payload = json_encode(array( + array( + 'Type' => 'TABLE', + 'Label' => 'dibi profiler (' . dibi::$numOfQueries . ' SQL queries took ' . sprintf('%0.3f', dibi::$totalTime * 1000) . ' ms)', + ), + self::$fireTable, + )); + foreach (str_split($payload, 4990) as $num => $s) { + $num++; + header("X-Wf-dibi-1-1-d$num: |$s|\\"); // protocol-, structure-, plugin-, message-index + } + header("X-Wf-dibi-1-1-d$num: |$s|"); + } + +} diff --git a/dibi/libs/DibiProfiler.php b/dibi/libs/DibiProfiler.php deleted file mode 100644 index cec0a74d..00000000 --- a/dibi/libs/DibiProfiler.php +++ /dev/null @@ -1,327 +0,0 @@ -addPanel($this); - eval('$tmp = Nette\Diagnostics\Debugger::$blueScreen;'); - $tmp->addPanel(array($this, 'renderException'), __CLASS__); - } elseif (is_callable('NDebugger::enable')) { - NDebugger::$bar->addPanel($this); - NDebugger::$blueScreen->addPanel(array($this, 'renderException'), __CLASS__); - } elseif (is_callable('Debugger::enable')) { - Debugger::$bar->addPanel($this); - Debugger::$blueScreen->addPanel(array($this, 'renderException'), __CLASS__); - } - - $this->useFirebug = isset($_SERVER['HTTP_USER_AGENT']) && strpos($_SERVER['HTTP_USER_AGENT'], 'FirePHP/'); - - if (isset($config['file'])) { - $this->setFile($config['file']); - } - - if (isset($config['filter'])) { - $this->setFilter($config['filter']); - } - - if (isset($config['explain'])) { - $this->explainQuery = (bool) $config['explain']; - } - } - - - - public function renderException($e) - { - if ($e instanceof DibiException && $e->getSql()) { - return array( - 'tab' => 'SQL', - 'panel' => dibi::dump($e->getSql(), TRUE), - ); - } - } - - - - /** - * @param string filename - * @return DibiProfiler provides a fluent interface - */ - public function setFile($file) - { - $this->file = $file; - return $this; - } - - - - /** - * @param int - * @return DibiProfiler provides a fluent interface - */ - public function setFilter($filter) - { - $this->filter = (int) $filter; - return $this; - } - - - - /** - * Before event notification. - * @param DibiConnection - * @param int event name - * @param string sql - * @return int - */ - public function before(DibiConnection $connection, $event, $sql = NULL) - { - $rc = new ReflectionClass('dibi'); - $dibiDir = dirname($rc->getFileName()) . DIRECTORY_SEPARATOR; - $source = NULL; - foreach (debug_backtrace(FALSE) as $row) { - if (isset($row['file']) && is_file($row['file']) && strpos($row['file'], $dibiDir) !== 0) { - $source = array($row['file'], (int) $row['line']); - break; - } - } - if ($event & self::QUERY) dibi::$numOfQueries++; - dibi::$elapsedTime = FALSE; - self::$tickets[] = array($connection, $event, trim($sql), -microtime(TRUE), NULL, $source); - end(self::$tickets); - return key(self::$tickets); - } - - - - /** - * After event notification. - * @param int - * @param DibiResult - * @return void - */ - public function after($ticket, $res = NULL) - { - if (!isset(self::$tickets[$ticket])) { - throw new InvalidArgumentException('Bad ticket number.'); - } - - $ticket = & self::$tickets[$ticket]; - $ticket[3] += microtime(TRUE); - list($connection, $event, $sql, $time, , $source) = $ticket; - - dibi::$elapsedTime = $time; - dibi::$totalTime += $time; - - if (($event & $this->filter) === 0) return; - - if ($event & self::QUERY) { - try { - $ticket[4] = $count = $res instanceof DibiResult ? count($res) : '-'; - } catch (Exception $e) { - $count = '?'; - } - - if (count(self::$fireTable) < self::$maxQueries) { - self::$fireTable[] = array( - sprintf('%0.3f', $time * 1000), - strlen($sql) > self::$maxLength ? substr($sql, 0, self::$maxLength) . '...' : $sql, - $count, - $connection->getConfig('driver') . '/' . $connection->getConfig('name') - ); - - if ($this->useFirebug && !headers_sent()) { - header('X-Wf-Protocol-dibi: http://meta.wildfirehq.org/Protocol/JsonStream/0.2'); - header('X-Wf-dibi-Plugin-1: http://meta.firephp.org/Wildfire/Plugin/FirePHP/Library-FirePHPCore/0.2.0'); - header('X-Wf-dibi-Structure-1: http://meta.firephp.org/Wildfire/Structure/FirePHP/FirebugConsole/0.1'); - - $payload = json_encode(array( - array( - 'Type' => 'TABLE', - 'Label' => 'dibi profiler (' . dibi::$numOfQueries . ' SQL queries took ' . sprintf('%0.3f', dibi::$totalTime * 1000) . ' ms)', - ), - self::$fireTable, - )); - foreach (str_split($payload, 4990) as $num => $s) { - $num++; - header("X-Wf-dibi-1-1-d$num: |$s|\\"); // protocol-, structure-, plugin-, message-index - } - header("X-Wf-dibi-1-1-d$num: |$s|"); - } - } - - if ($this->file) { - $this->writeFile( - "OK: " . $sql - . ($res instanceof DibiResult ? ";\n-- rows: " . $count : '') - . "\n-- takes: " . sprintf('%0.3f', $time * 1000) . ' ms' - . "\n-- source: " . implode(':', $source) - . "\n-- driver: " . $connection->getConfig('driver') . '/' . $connection->getConfig('name') - . "\n-- " . date('Y-m-d H:i:s') - . "\n\n" - ); - } - } - } - - - - /** - * After exception notification. - * @param DibiDriverException - * @return void - */ - public function exception(DibiDriverException $exception) - { - if ((self::EXCEPTION & $this->filter) === 0) return; - - if ($this->useFirebug) { - // TODO: implement - } - - if ($this->file) { - $message = $exception->getMessage(); - $code = $exception->getCode(); - if ($code) { - $message = "[$code] $message"; - } - $this->writeFile( - "ERROR: $message" - . "\n-- SQL: " . dibi::$sql - . "\n-- driver: " //. $connection->getConfig('driver') - . ";\n-- " . date('Y-m-d H:i:s') - . "\n\n" - ); - } - } - - - - private function writeFile($message) - { - $handle = fopen($this->file, 'a'); - if (!$handle) return; // or throw exception? - flock($handle, LOCK_EX); - fwrite($handle, $message); - fclose($handle); - } - - - - /********************* interface Nette\Diagnostics\IBarPanel ****************d*g**/ - - - - /** - * Returns HTML code for custom tab. - * @return mixed - */ - public function getTab() - { - return '' - . dibi::$numOfQueries . ' queries'; - } - - - - /** - * Returns HTML code for custom panel. - * @return mixed - */ - public function getPanel() - { - $s = NULL; - $h = 'htmlSpecialChars'; - foreach (self::$tickets as $i => $ticket) { - list($connection, $event, $sql, $time, $count, $source) = $ticket; - if (!($event & self::QUERY)) continue; - - $explain = NULL; // EXPLAIN is called here to work SELECT FOUND_ROWS() - if ($this->explainQuery && $event === self::SELECT) { - try { - $explain = dibi::dump($connection->setProfiler(NULL)->nativeQuery('EXPLAIN ' . $sql), TRUE); - } catch (DibiException $e) {} - $connection->setProfiler($this); - } - - $s .= '' . sprintf('%0.3f', $time * 1000); - if ($explain) { - $s .= "
explain ►"; - } - - $s .= '' . dibi::dump(strlen($sql) > self::$maxLength ? substr($sql, 0, self::$maxLength) . '...' : $sql, TRUE); - if ($explain) { - $s .= "
{$explain}
"; - } - if ($source) { - list($file, $line) = $source; - $s .= "{$h(basename(dirname($file)) . '/' . basename($file))}:$line"; - } - - $s .= "{$count}{$h($connection->getConfig('driver') . '/' . $connection->getConfig('name'))}"; - } - - return $s === NULL ? '' : - ' -

Queries: ' . dibi::$numOfQueries . (dibi::$totalTime === NULL ? '' : ', time: ' . sprintf('%0.3f', dibi::$totalTime * 1000) . ' ms') . '

-
- - ' . $s . ' -
Time msSQL StatementRowsConnection
-
'; - } - -} diff --git a/dibi/libs/interfaces.php b/dibi/libs/interfaces.php index 1e5a6e05..c4bc556e 100644 --- a/dibi/libs/interfaces.php +++ b/dibi/libs/interfaces.php @@ -36,55 +36,6 @@ interface IDibiVariable -/** - * Defines method that must profiler implement. - */ -interface IDibiProfiler -{ - /** event type */ - const CONNECT = 1, - SELECT = 4, - INSERT = 8, - DELETE = 16, - UPDATE = 32, - QUERY = 60, // SELECT | INSERT | DELETE | UPDATE - BEGIN = 64, - COMMIT = 128, - ROLLBACK = 256, - TRANSACTION = 448, // BEGIN | COMMIT | ROLLBACK - EXCEPTION = 512, - ALL = 1023; - - /** - * Before event notification. - * @param DibiConnection - * @param int event name - * @param string sql - * @return int - */ - function before(DibiConnection $connection, $event, $sql = NULL); - - /** - * After event notification. - * @param int - * @param DibiResult - * @return void - */ - function after($ticket, $result = NULL); - - /** - * After exception notification. - * @param DibiDriverException - * @return void - */ - function exception(DibiDriverException $exception); - -} - - - - - /** * dibi driver interface. */ diff --git a/examples/using-logger.php b/examples/using-logger.php index 6833574d..bb7d02f8 100644 --- a/examples/using-logger.php +++ b/examples/using-logger.php @@ -13,14 +13,14 @@ date_default_timezone_set('Europe/Prague'); dibi::connect(array( 'driver' => 'sqlite', 'database' => 'data/sample.sdb', - 'profiler' => TRUE, + // enable query logging to this file + 'profiler' => array( + 'run' => TRUE, + 'file' => 'data/log.sql', + ), )); -// enable query logging to this file -dibi::getProfiler()->setFile('data/log.sql'); - - try { $res = dibi::query('SELECT * FROM [customers] WHERE [customer_id] = %i', 1);