Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/matomo-org/matomo.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormattpiwik <matthieu.aubry@gmail.com>2008-10-28 14:42:44 +0300
committermattpiwik <matthieu.aubry@gmail.com>2008-10-28 14:42:44 +0300
commit94e9bc0b97f85b2c6f9c56b7b082319b34e8dd0e (patch)
tree40acb631d96976a11160e9f4317cbb47a023c725 /core/Tracker/Db.php
parent18ff3fbb13d94067d18817b1bb967ef189454d39 (diff)
- renaming all instances of LogStats to Tracker for clarity
- improving error message to be prettier - adding footer in all admin pages for consistency git-svn-id: http://dev.piwik.org/svn/trunk@649 59fd770c-687e-43c8-a1e3-f5a4ff64c105
Diffstat (limited to 'core/Tracker/Db.php')
-rw-r--r--core/Tracker/Db.php264
1 files changed, 264 insertions, 0 deletions
diff --git a/core/Tracker/Db.php b/core/Tracker/Db.php
new file mode 100644
index 0000000000..13d23d1a26
--- /dev/null
+++ b/core/Tracker/Db.php
@@ -0,0 +1,264 @@
+<?php
+/**
+ * Piwik - Open source web analytics
+ *
+ * @link http://piwik.org
+ * @license http://www.gnu.org/licenses/gpl-3.0.html Gpl v3 or later
+ * @version $Id: Db.php 522 2008-06-11 00:31:03Z matt $
+ *
+ * @package Piwik_Tracker
+ */
+
+/**
+ * Simple database PDO wrapper.
+ * We can't afford to have a dependency with the Zend_Db module in Tracker.
+ * We wrote this simple class
+ *
+ * @package Piwik_Tracker
+ */
+class Piwik_Tracker_Db
+{
+ private $connection = null;
+ private $username;
+ private $password;
+
+ static private $profiling = false;
+
+ protected $queriesProfiling = array();
+
+ /**
+ * Builds the DB object
+ */
+ public function __construct( $host, $username, $password, $dbname, $port, $driverName = 'mysql')
+ {
+ $this->dsn = $driverName.":dbname=$dbname;host=$host;port=$port";
+ $this->username = $username;
+ $this->password = $password;
+ }
+
+ public function __destruct()
+ {
+ $this->connection = null;
+ }
+
+ /**
+ * Returns true if the SQL profiler is enabled
+ * Only used by the unit test that tests that the profiler is off on a production server
+ *
+ * @return bool
+ */
+ static public function isProfilingEnabled()
+ {
+ return self::$profiling;
+ }
+
+ /**
+ * Enables the SQL profiling.
+ * For each query, saves in the DB the time spent on this query.
+ * Very useful to see the slow query under heavy load.
+ * You can then use Piwik::printSqlProfilingReportTracker();
+ * to display the SQLProfiling report and see which queries take time, etc.
+ */
+ static public function enableProfiling()
+ {
+ self::$profiling = true;
+ }
+
+ /**
+ * Disables the SQL profiling logging.
+ */
+ static public function disableProfiling()
+ {
+ self::$profiling = false;
+ }
+
+ /**
+ * Connects to the DB
+ *
+ * @throws Exception if there was an error connecting the DB
+ */
+ public function connect()
+ {
+ if(self::$profiling)
+ {
+ $timer = $this->initProfiler();
+ }
+
+ $this->connection = new PDO($this->dsn, $this->username, $this->password);
+ $this->connection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
+ // we may want to setAttribute(PDO::ATTR_TIMEOUT ) to a few seconds (default is 60) in case the DB is locked
+ // the piwik.php would stay waiting for the database... bad!
+ // we delete the password from this object "just in case" it could be printed
+ $this->password = '';
+
+ if(self::$profiling)
+ {
+ $this->recordQueryProfile('connect', $timer);
+ }
+ }
+
+ /**
+ * Disconnects from the Mysql server
+ *
+ * @return void
+ */
+ public function disconnect()
+ {
+ if(self::$profiling)
+ {
+ $this->recordProfiling();
+ }
+ $this->connection = null;
+ }
+
+ /**
+ * Returns the table name prefixed by the table prefix.
+ *
+ * @param string The table name to prefix, ie "log_visit"
+ * @return string The table name prefixed, ie "piwik-production_log_visit"
+ */
+ static public function prefixTable( $suffix )
+ {
+ static $prefix;
+ if (!isset($prefix)) {
+ $prefix = Piwik_Tracker_Config::getInstance()->database['tables_prefix'];
+ }
+ return $prefix . $suffix;
+ }
+
+ /**
+ * Returns an array containing all the rows of a query result, using optional bound parameters.
+ *
+ * @param string Query
+ * @param array Parameters to bind
+ * @see also query()
+ * @throws Exception if an exception occured
+ */
+ public function fetchAll( $query, $parameters = array() )
+ {
+ try {
+ $sth = $this->query( $query, $parameters );
+ if($sth === false)
+ {
+ return false;
+ }
+ return $sth->fetchAll(PDO::FETCH_ASSOC);
+ } catch (PDOException $e) {
+ throw new Exception("Error query: ".$e->getMessage());
+ }
+ }
+
+ /**
+ * Returns the first row of a query result, using optional bound parameters.
+ *
+ * @param string Query
+ * @param array Parameters to bind
+ * @see also query()
+ *
+ * @throws Exception if an exception occured
+ */
+ public function fetch( $query, $parameters = array() )
+ {
+ try {
+ $sth = $this->query( $query, $parameters );
+ if($sth === false)
+ {
+ return false;
+ }
+ return $sth->fetch(PDO::FETCH_ASSOC);
+ } catch (PDOException $e) {
+ throw new Exception("Error query: ".$e->getMessage());
+ }
+ }
+
+ /**
+ * Executes a query, using optional bound parameters.
+ *
+ * @param string Query
+ * @param array Parameters to bind
+ *
+ * @return PDOStatement or false if failed
+ * @throw Exception if an exception occured
+ */
+ public function query($query, $parameters = array())
+ {
+ if(is_null($this->connection))
+ {
+ return false;
+ }
+ try {
+ if(self::$profiling)
+ {
+ $timer = $this->initProfiler();
+ }
+
+ $sth = $this->connection->prepare($query);
+ $sth->execute( $parameters );
+
+ if(self::$profiling)
+ {
+ $this->recordQueryProfile($query, $timer);
+ }
+ return $sth;
+ } catch (PDOException $e) {
+ throw new Exception("Error query: ".$e->getMessage());
+ }
+ }
+
+ protected function initProfiler()
+ {
+ require_once "Timer.php";
+ return new Piwik_Timer;
+ }
+
+ protected function recordQueryProfile( $query, $timer )
+ {
+ if(!isset($this->queriesProfiling[$query])) $this->queriesProfiling[$query] = array('sum_time_ms' => 0, 'count' => 0);
+ $time = $timer->getTimeMs(2);
+ $time += $this->queriesProfiling[$query]['sum_time_ms'];
+ $count = $this->queriesProfiling[$query]['count'] + 1;
+ $this->queriesProfiling[$query] = array('sum_time_ms' => $time, 'count' => $count);
+ }
+
+ /**
+ * Returns the last inserted ID in the DB
+ * Wrapper of PDO::lastInsertId()
+ *
+ * @return int
+ */
+ public function lastInsertId()
+ {
+ return $this->connection->lastInsertId();
+ }
+
+ /**
+ * When destroyed, if SQL profiled enabled, logs the SQL profiling information
+ */
+ public function recordProfiling()
+ {
+ if(is_null($this->connection))
+ {
+ return;
+ }
+
+ // turn off the profiler so we don't profile the following queries
+ self::$profiling = false;
+
+ foreach($this->queriesProfiling as $query => $info)
+ {
+ $time = $info['sum_time_ms'];
+ $count = $info['count'];
+
+ $queryProfiling = "INSERT INTO ".$this->prefixTable('log_profiling')."
+ (query,count,sum_time_ms) VALUES (?,$count,$time)
+ ON DUPLICATE KEY
+ UPDATE count=count+$count,sum_time_ms=sum_time_ms+$time";
+ $this->query($queryProfiling,array($query));
+ }
+
+ // turn back on profiling
+ self::$profiling = true;
+ }
+}
+
+