From 7d87f843df8a4fd4f083916bb610e9dd54ba7e79 Mon Sep 17 00:00:00 2001 From: Andrey Kutejko Date: Sun, 17 Aug 2014 08:36:05 +0300 Subject: [PATCH] new sql profiler --- ipf/database.php | 95 +++++++++++++++++++++++++++++++-- ipf/orm/connection/profiler.php | 34 ------------ ipf/project.php | 10 +--- ipf/project_template.php | 28 ---------- 4 files changed, 94 insertions(+), 73 deletions(-) delete mode 100644 ipf/orm/connection/profiler.php diff --git a/ipf/database.php b/ipf/database.php index 895a9b4..9250d86 100644 --- a/ipf/database.php +++ b/ipf/database.php @@ -2,8 +2,11 @@ class IPF_Database { - public static function connect($database) + public static function connect($database=null) { + if (!$database) + $database = IPF::get('database'); + $driver = \PFF\Arr::get($database, 'driver', 'mysql'); $dsn = self::makeDsnForPDO($driver, @@ -11,8 +14,10 @@ class IPF_Database \PFF\Arr::get($database, 'port'), \PFF\Arr::get($database, 'database')); - $conn = new PDO($dsn, - \PFF\Arr::get($database, 'username'), + $pdoClass = IPF::get('debug') ? 'PDOProfile' : 'PDO'; + + $conn = new $pdoClass($dsn, + \PFF\Arr::get($database, 'username'), \PFF\Arr::get($database, 'password')); $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); @@ -55,3 +60,87 @@ class IPF_Database } } + + +class PDOProfile extends PDO +{ + public function __construct($dsn, $username=null, $password=null, $options=null) + { + parent::__construct($dsn, $username, $password, $options); + $this->setAttribute(PDO::ATTR_STATEMENT_CLASS, array('PDOProfileStatement', array($this))); + + $this->colors = array( + "\033[1;35m", // magenta + "\033[1;36m", // cyan + ); + } + + public function exec($statement) + { + $start = microtime(true); + $result = parent::exec($statement); + $exec_time = microtime(true) - $start; + $this->report($statement, null, $exec_time, $exec_time); + return $result; + } + + public function prepare($q, $driver_options=array()) + { + $stmt = parent::prepare($q, $driver_options); + $stmt->q = $q; + return $stmt; + } + + public function query($q) + { + $stmt = parent::query($q); + $stmt->q = $q; + return $stmt; + } + + private $colors, $color = 0; + + private function getColor() + { + $color = $this->colors[$this->color]; + $this->color = ($this->color + 1) % count($this->colors); + return $color; + } + + public function report($query, $params, $total_time, $exec_time) + { + $color = $this->getColor(); + error_log($color.$query."\033[0m"); + if ($params) + error_log($color.trim(print_r($params, 1))."\033[0m"); + error_log($color.sprintf('Query time: %0.3fms Total time: %0.3fms', $exec_time * 1000, $total_time * 1000)."\033[0m"); + } +} + +class PDOProfileStatement extends PDOStatement +{ + public $q = 'UNKNOWN QUERY', $params = null; + private $start, $execute_time; + + protected function __construct($pdo) + { + $this->pdo = $pdo; + $this->start = microtime(true); + } + + function execute($params=null) + { + $this->params = $params; + $start = microtime(true); + $result = $params ? parent::execute($params) : parent::execute(); + $this->execute_time = microtime(true) - $start; + return $result; + } + + function __destruct() + { + $total = microtime(true) - $this->start; + $this->pdo->report($this->q, $this->params, $total, $this->execute_time); + } +} + diff --git a/ipf/orm/connection/profiler.php b/ipf/orm/connection/profiler.php deleted file mode 100644 index 4284fcb..0000000 --- a/ipf/orm/connection/profiler.php +++ /dev/null @@ -1,34 +0,0 @@ -start(); - - if ( ! in_array($a[0], $this->events, true)) { - $this->events[] = $a[0]; - } - } else { - // after-event listener found - $a[0]->end(); - } - } -} - diff --git a/ipf/project.php b/ipf/project.php index 2a19583..01c16aa 100644 --- a/ipf/project.php +++ b/ipf/project.php @@ -5,7 +5,6 @@ final class IPF_Project private $apps = array(); public $router = null; public $request = null; - public $sqlProfiler = null; static private $instance = NULL; @@ -88,17 +87,12 @@ final class IPF_Project public function run() { + \PFF\Container::setFactory('databaseConnection', array('IPF_Database', 'connect')); + if (IPF::get('debug')) { error_reporting(E_ALL); - - $this->sqlProfiler = new IPF_ORM_Connection_Profiler(); - IPF_ORM_Manager::getInstance()->dbListeners[] = $this->sqlProfiler; } - \PFF\Container::setFactory('databaseConnection', function() { - return IPF_Database::connect(IPF::get('database')); - }); - if (php_sapi_name() === 'cli') { $cli = new IPF_Cli; $cli->run(); diff --git a/ipf/project_template.php b/ipf/project_template.php index 5832d02..5428001 100644 --- a/ipf/project_template.php +++ b/ipf/project_template.php @@ -31,7 +31,6 @@ final class IPF_Project_Template $e->tags['url'] = 'IPF_Project_Template_Tag_Url'; $e->tags['params'] = 'IPF_Project_Template_Tag_Params'; - $e->tags['sql'] = 'IPF_Project_Template_Tag_Sql'; // extra tags $e->tags = array_merge(IPF::get('template_tags', array()), $e->tags); @@ -119,30 +118,3 @@ class IPF_Project_Template_Tag_Params extends IPF_Template_Tag } } -class IPF_Project_Template_Tag_Sql extends IPF_Template_Tag -{ - function start() - { - $profiler = IPF_Project::getInstance()->sqlProfiler; - if ($profiler !== null) { - echo '

Sql Debug

set debug to false in settings project for disable sql profiler
'; - $time = 0; - foreach ($profiler->events as $event) { - $time += $event->getElapsedSecs(); - $name = $event->getName(); - if ($name=='fetch' || $name=='prepare' || $name=='connect') - continue; - echo "
\n" . $name . " " . sprintf("%f", $event->getElapsedSecs()) . "
\n"; - echo $event->getQuery() . "
\n"; - $params = $event->getParams(); - if( ! empty($params)) { - var_dump($params); - print "
\n"; - } - } - echo "
\nTotal time: " . $time . " (without prepare and fetch event)
\n"; - echo '
'; - } - } -} - -- 2.49.0