summaryrefslogtreecommitdiffstats
path: root/vendor/gipfl/zfdb/src/Profiler.php
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/gipfl/zfdb/src/Profiler.php')
-rw-r--r--vendor/gipfl/zfdb/src/Profiler.php463
1 files changed, 463 insertions, 0 deletions
diff --git a/vendor/gipfl/zfdb/src/Profiler.php b/vendor/gipfl/zfdb/src/Profiler.php
new file mode 100644
index 0000000..026fa0e
--- /dev/null
+++ b/vendor/gipfl/zfdb/src/Profiler.php
@@ -0,0 +1,463 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id$
+ */
+namespace gipfl\ZfDb;
+
+use gipfl\ZfDb\Profiler\ProfilerException;
+use gipfl\ZfDb\Profiler\ProfilerQuery;
+
+/**
+ * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Profiler
+{
+ /**
+ * A connection operation or selecting a database.
+ */
+ const CONNECT = 1;
+
+ /**
+ * Any general database query that does not fit into the other constants.
+ */
+ const QUERY = 2;
+
+ /**
+ * Adding new data to the database, such as SQL's INSERT.
+ */
+ const INSERT = 4;
+
+ /**
+ * Updating existing information in the database, such as SQL's UPDATE.
+ *
+ */
+ const UPDATE = 8;
+
+ /**
+ * An operation related to deleting data in the database,
+ * such as SQL's DELETE.
+ */
+ const DELETE = 16;
+
+ /**
+ * Retrieving information from the database, such as SQL's SELECT.
+ */
+ const SELECT = 32;
+
+ /**
+ * Transactional operation, such as start transaction, commit, or rollback.
+ */
+ const TRANSACTION = 64;
+
+ /**
+ * Inform that a query is stored (in case of filtering)
+ */
+ const STORED = 'stored';
+
+ /**
+ * Inform that a query is ignored (in case of filtering)
+ */
+ const IGNORED = 'ignored';
+
+ /**
+ * Array of ProfilerQuery objects.
+ *
+ * @var array
+ */
+ protected $_queryProfiles = array();
+
+ /**
+ * Stores enabled state of the profiler. If set to False, calls to
+ * queryStart() will simply be ignored.
+ *
+ * @var boolean
+ */
+ protected $_enabled = false;
+
+ /**
+ * Stores the number of seconds to filter. NULL if filtering by time is
+ * disabled. If an integer is stored here, profiles whose elapsed time
+ * is less than this value in seconds will be unset from
+ * the self::$_queryProfiles array.
+ *
+ * @var integer
+ */
+ protected $_filterElapsedSecs = null;
+
+ /**
+ * Logical OR of any of the filter constants. NULL if filtering by query
+ * type is disable. If an integer is stored here, it is the logical OR of
+ * any of the query type constants. When the query ends, if it is not
+ * one of the types specified, it will be unset from the
+ * self::$_queryProfiles array.
+ *
+ * @var integer
+ */
+ protected $_filterTypes = null;
+
+ /**
+ * Class constructor. The profiler is disabled by default unless it is
+ * specifically enabled by passing in $enabled here or calling setEnabled().
+ *
+ * @param boolean $enabled
+ * @return void
+ */
+ public function __construct($enabled = false)
+ {
+ $this->setEnabled($enabled);
+ }
+
+ /**
+ * Enable or disable the profiler. If $enable is false, the profiler
+ * is disabled and will not log any queries sent to it.
+ *
+ * @param boolean $enable
+ * @return Profiler Provides a fluent interface
+ */
+ public function setEnabled($enable)
+ {
+ $this->_enabled = (boolean) $enable;
+
+ return $this;
+ }
+
+ /**
+ * Get the current state of enable. If True is returned,
+ * the profiler is enabled.
+ *
+ * @return boolean
+ */
+ public function getEnabled()
+ {
+ return $this->_enabled;
+ }
+
+ /**
+ * Sets a minimum number of seconds for saving query profiles. If this
+ * is set, only those queries whose elapsed time is equal or greater than
+ * $minimumSeconds will be saved. To save all queries regardless of
+ * elapsed time, set $minimumSeconds to null.
+ *
+ * @param integer $minimumSeconds OPTIONAL
+ * @return Profiler Provides a fluent interface
+ */
+ public function setFilterElapsedSecs($minimumSeconds = null)
+ {
+ if (null === $minimumSeconds) {
+ $this->_filterElapsedSecs = null;
+ } else {
+ $this->_filterElapsedSecs = (integer) $minimumSeconds;
+ }
+
+ return $this;
+ }
+
+ /**
+ * Returns the minimum number of seconds for saving query profiles, or null if
+ * query profiles are saved regardless of elapsed time.
+ *
+ * @return integer|null
+ */
+ public function getFilterElapsedSecs()
+ {
+ return $this->_filterElapsedSecs;
+ }
+
+ /**
+ * Sets the types of query profiles to save. Set $queryType to one of
+ * the Zend_Db_Profiler::* constants to only save profiles for that type of
+ * query. To save more than one type, logical OR them together. To
+ * save all queries regardless of type, set $queryType to null.
+ *
+ * @param integer $queryTypes OPTIONAL
+ * @return Profiler Provides a fluent interface
+ */
+ public function setFilterQueryType($queryTypes = null)
+ {
+ $this->_filterTypes = $queryTypes;
+
+ return $this;
+ }
+
+ /**
+ * Returns the types of query profiles saved, or null if queries are saved regardless
+ * of their types.
+ *
+ * @return integer|null
+ * @see Profiler::setFilterQueryType()
+ */
+ public function getFilterQueryType()
+ {
+ return $this->_filterTypes;
+ }
+
+ /**
+ * Clears the history of any past query profiles. This is relentless
+ * and will even clear queries that were started and may not have
+ * been marked as ended.
+ *
+ * @return Profiler Provides a fluent interface
+ */
+ public function clear()
+ {
+ $this->_queryProfiles = array();
+
+ return $this;
+ }
+
+ /**
+ * Clone a profiler query
+ *
+ * @param ProfilerQuery $query
+ * @return integer or null
+ */
+ public function queryClone(ProfilerQuery $query)
+ {
+ $this->_queryProfiles[] = clone $query;
+
+ end($this->_queryProfiles);
+
+ return key($this->_queryProfiles);
+ }
+
+ /**
+ * Starts a query. Creates a new query profile object (ProfilerQuery)
+ * and returns the "query profiler handle". Run the query, then call
+ * queryEnd() and pass it this handle to make the query as ended and
+ * record the time. If the profiler is not enabled, this takes no
+ * action and immediately returns null.
+ *
+ * @param string $queryText SQL statement
+ * @param integer $queryType OPTIONAL Type of query, one of the Zend_Db_Profiler::* constants
+ * @return integer|null
+ */
+ public function queryStart($queryText, $queryType = null)
+ {
+ if (!$this->_enabled) {
+ return null;
+ }
+
+ // make sure we have a query type
+ if (null === $queryType) {
+ switch (strtolower(substr(ltrim($queryText), 0, 6))) {
+ case 'insert':
+ $queryType = self::INSERT;
+ break;
+ case 'update':
+ $queryType = self::UPDATE;
+ break;
+ case 'delete':
+ $queryType = self::DELETE;
+ break;
+ case 'select':
+ $queryType = self::SELECT;
+ break;
+ default:
+ $queryType = self::QUERY;
+ break;
+ }
+ }
+
+ /**
+ * @see ProfilerQuery
+ */
+ $this->_queryProfiles[] = new ProfilerQuery($queryText, $queryType);
+
+ end($this->_queryProfiles);
+
+ return key($this->_queryProfiles);
+ }
+
+ /**
+ * Ends a query. Pass it the handle that was returned by queryStart().
+ * This will mark the query as ended and save the time.
+ *
+ * @param integer $queryId
+ * @throws ProfilerException
+ * @return string Inform that a query is stored or ignored.
+ */
+ public function queryEnd($queryId)
+ {
+ // Don't do anything if the Zend_Db_Profiler is not enabled.
+ if (!$this->_enabled) {
+ return self::IGNORED;
+ }
+
+ // Check for a valid query handle.
+ if (!isset($this->_queryProfiles[$queryId])) {
+ /**
+ * @see ProfilerException
+ */
+ throw new ProfilerException("Profiler has no query with handle '$queryId'.");
+ }
+
+ $qp = $this->_queryProfiles[$queryId];
+
+ // Ensure that the query profile has not already ended
+ if ($qp->hasEnded()) {
+ /**
+ * @see ProfilerException
+ */
+ throw new ProfilerException("Query with profiler handle '$queryId' has already ended.");
+ }
+
+ // End the query profile so that the elapsed time can be calculated.
+ $qp->end();
+
+ /**
+ * If filtering by elapsed time is enabled, only keep the profile if
+ * it ran for the minimum time.
+ */
+ if (null !== $this->_filterElapsedSecs && $qp->getElapsedSecs() < $this->_filterElapsedSecs) {
+ unset($this->_queryProfiles[$queryId]);
+ return self::IGNORED;
+ }
+
+ /**
+ * If filtering by query type is enabled, only keep the query if
+ * it was one of the allowed types.
+ */
+ if (null !== $this->_filterTypes && !($qp->getQueryType() & $this->_filterTypes)) {
+ unset($this->_queryProfiles[$queryId]);
+ return self::IGNORED;
+ }
+
+ return self::STORED;
+ }
+
+ /**
+ * Get a profile for a query. Pass it the same handle that was returned
+ * by queryStart() and it will return a ProfilerQuery object.
+ *
+ * @param integer $queryId
+ * @throws ProfilerException
+ * @return ProfilerQuery
+ */
+ public function getQueryProfile($queryId)
+ {
+ if (!array_key_exists($queryId, $this->_queryProfiles)) {
+ /**
+ * @see ProfilerException
+ */
+ throw new ProfilerException("Query handle '$queryId' not found in profiler log.");
+ }
+
+ return $this->_queryProfiles[$queryId];
+ }
+
+ /**
+ * Get an array of query profiles (ProfilerQuery objects). If $queryType
+ * is set to one of the Zend_Db_Profiler::* constants then only queries of that
+ * type will be returned. Normally, queries that have not yet ended will
+ * not be returned unless $showUnfinished is set to True. If no
+ * queries were found, False is returned. The returned array is indexed by the query
+ * profile handles.
+ *
+ * @param integer $queryType
+ * @param boolean $showUnfinished
+ * @return array|false
+ */
+ public function getQueryProfiles($queryType = null, $showUnfinished = false)
+ {
+ $queryProfiles = array();
+ foreach ($this->_queryProfiles as $key => $qp) {
+ if ($queryType === null) {
+ $condition = true;
+ } else {
+ $condition = ($qp->getQueryType() & $queryType);
+ }
+
+ if (($qp->hasEnded() || $showUnfinished) && $condition) {
+ $queryProfiles[$key] = $qp;
+ }
+ }
+
+ if (empty($queryProfiles)) {
+ $queryProfiles = false;
+ }
+
+ return $queryProfiles;
+ }
+
+ /**
+ * Get the total elapsed time (in seconds) of all of the profiled queries.
+ * Only queries that have ended will be counted. If $queryType is set to
+ * one or more of the Zend_Db_Profiler::* constants, the elapsed time will be calculated
+ * only for queries of the given type(s).
+ *
+ * @param integer $queryType OPTIONAL
+ * @return float
+ */
+ public function getTotalElapsedSecs($queryType = null)
+ {
+ $elapsedSecs = 0;
+ foreach ($this->_queryProfiles as $key => $qp) {
+ if (null === $queryType) {
+ $condition = true;
+ } else {
+ $condition = ($qp->getQueryType() & $queryType);
+ }
+ if (($qp->hasEnded()) && $condition) {
+ $elapsedSecs += $qp->getElapsedSecs();
+ }
+ }
+ return $elapsedSecs;
+ }
+
+ /**
+ * Get the total number of queries that have been profiled. Only queries that have ended will
+ * be counted. If $queryType is set to one of the Zend_Db_Profiler::* constants, only queries of
+ * that type will be counted.
+ *
+ * @param integer $queryType OPTIONAL
+ * @return integer
+ */
+ public function getTotalNumQueries($queryType = null)
+ {
+ if (null === $queryType) {
+ return count($this->_queryProfiles);
+ }
+
+ $numQueries = 0;
+ foreach ($this->_queryProfiles as $qp) {
+ if ($qp->hasEnded() && ($qp->getQueryType() & $queryType)) {
+ $numQueries++;
+ }
+ }
+
+ return $numQueries;
+ }
+
+ /**
+ * Get the ProfilerQuery object for the last query that was run, regardless if it has
+ * ended or not. If the query has not ended, its end time will be null. If no queries have
+ * been profiled, false is returned.
+ *
+ * @return ProfilerQuery|false
+ */
+ public function getLastQueryProfile()
+ {
+ if (empty($this->_queryProfiles)) {
+ return false;
+ }
+
+ end($this->_queryProfiles);
+
+ return current($this->_queryProfiles);
+ }
+}