]> git.andy128k.dev Git - ipf.git/commitdiff
new sql profiler
authorAndrey Kutejko <andy128k@gmail.com>
Sun, 17 Aug 2014 05:36:05 +0000 (08:36 +0300)
committerAndrey Kutejko <andy128k@gmail.com>
Sun, 17 Aug 2014 05:36:05 +0000 (08:36 +0300)
ipf/database.php
ipf/orm/connection/profiler.php [deleted file]
ipf/project.php
ipf/project_template.php

index 895a9b407f6eba7a26ca6d86f09e919d59ec3cd5..9250d8671d96b8bdd576275d72a239050278e7ea 100644 (file)
@@ -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 (file)
index 4284fcb..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-<?php
-
-class IPF_ORM_Connection_Profiler
-{
-    private $listeners  = array('query',
-                                'prepare',
-                                'commit',
-                                'rollback',
-                                'connect',
-                                'begintransaction',
-                                'exec',
-                                'execute');
-
-    public $events = array();
-
-    public function __call($m, $a)
-    {
-        if (!($a[0] instanceof IPF_ORM_Event))
-            return;
-
-        if (substr($m, 0, 3) === 'pre') {
-            // pre-event listener found
-            $a[0]->start();
-
-            if ( ! in_array($a[0], $this->events, true)) {
-                $this->events[] = $a[0];
-            }
-        } else {
-            // after-event listener found
-            $a[0]->end();
-        }
-    }
-}
-
index 2a195834f2aa66902a0c963badff58516a2d9d13..01c16aa66bcd211b9b2c7bf99b972fb024b78e96 100644 (file)
@@ -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();
index 5832d026f6320569af480f233126bcf5db1d76ea..5428001fc69f4eec83394b40df1fefe5a19dccdb 100644 (file)
@@ -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 '<div style="padding:10px; margin:10px; background:#eee; border:1px dashed #888;"><h3>Sql Debug</h3><div style="color:#888">set <i>debug</i> to false in settings project for disable sql profiler</div>';
-            $time = 0;
-            foreach ($profiler->events as $event) {
-                $time += $event->getElapsedSecs();
-                $name = $event->getName();
-                if ($name=='fetch' || $name=='prepare' || $name=='connect')
-                    continue;
-                echo "<br>\n<b>" . $name . "</b> " . sprintf("%f", $event->getElapsedSecs()) . "<br>\n";
-                echo $event->getQuery() . "<br>\n";
-                $params = $event->getParams();
-                if( ! empty($params)) {
-                    var_dump($params);
-                    print "<br>\n";
-                }
-            }
-            echo "<br>\n<b>Total time:</b> " . $time  . " (without prepare and fetch event)<br>\n";
-            echo '</div>';
-        }
-    }
-}
-