Overview

Packages

  • Auth
  • Config
  • Controller
  • Date
  • Db
  • Feed
    • Abstract
    • Writers
  • File
    • Decorator
  • Form
    • Element
  • Image
  • Log
    • Writer
  • Net
    • Exception
    • REST
  • None
  • PHP
  • PHPMailer
  • Session
  • Util
  • Validate
    • Validator
  • Zend
    • Db
      • Adapter
      • Expr
      • Profiler
      • Select
      • Statement
      • Table
    • Loader
      • Autoloader
      • PluginLoader
    • Registry

Classes

  • Zend_Db_Profiler
  • Zend_Db_Profiler_Firebug
  • Zend_Db_Profiler_Query

Exceptions

  • Zend_Db_Profiler_Exception
  • Overview
  • Package
  • Class
  • Tree
  1: <?php
  2: /**
  3:  * Zend Framework
  4:  *
  5:  * LICENSE
  6:  *
  7:  * This source file is subject to the new BSD license that is bundled
  8:  * with this package in the file LICENSE.txt.
  9:  * It is also available through the world-wide-web at this URL:
 10:  * http://framework.zend.com/license/new-bsd
 11:  * If you did not receive a copy of the license and are unable to
 12:  * obtain it through the world-wide-web, please send an email
 13:  * to license@zend.com so we can send you a copy immediately.
 14:  *
 15:  * @category   Zend
 16:  * @package    Zend_Db
 17:  * @subpackage Profiler
 18:  * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
 19:  * @license    http://framework.zend.com/license/new-bsd     New BSD License
 20:  * @version    $Id: Profiler.php 20096 2010-01-06 02:05:09Z bkarwin $
 21:  */
 22: 
 23: 
 24: /**
 25:  * @category   Zend
 26:  * @package    Zend_Db
 27:  * @subpackage Profiler
 28:  * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
 29:  * @license    http://framework.zend.com/license/new-bsd     New BSD License
 30:  */
 31: class Zend_Db_Profiler
 32: {
 33: 
 34:     /**
 35:      * A connection operation or selecting a database.
 36:      */
 37:     const CONNECT = 1;
 38: 
 39:     /**
 40:      * Any general database query that does not fit into the other constants.
 41:      */
 42:     const QUERY = 2;
 43: 
 44:     /**
 45:      * Adding new data to the database, such as SQL's INSERT.
 46:      */
 47:     const INSERT = 4;
 48: 
 49:     /**
 50:      * Updating existing information in the database, such as SQL's UPDATE.
 51:      *
 52:      */
 53:     const UPDATE = 8;
 54: 
 55:     /**
 56:      * An operation related to deleting data in the database,
 57:      * such as SQL's DELETE.
 58:      */
 59:     const DELETE = 16;
 60: 
 61:     /**
 62:      * Retrieving information from the database, such as SQL's SELECT.
 63:      */
 64:     const SELECT = 32;
 65: 
 66:     /**
 67:      * Transactional operation, such as start transaction, commit, or rollback.
 68:      */
 69:     const TRANSACTION = 64;
 70: 
 71:     /**
 72:      * Inform that a query is stored (in case of filtering)
 73:      */
 74:     const STORED = 'stored';
 75: 
 76:     /**
 77:      * Inform that a query is ignored (in case of filtering)
 78:      */
 79:     const IGNORED = 'ignored';
 80: 
 81:     /**
 82:      * Array of Zend_Db_Profiler_Query objects.
 83:      *
 84:      * @var array
 85:      */
 86:     protected $_queryProfiles = array();
 87: 
 88:     /**
 89:      * Stores enabled state of the profiler.  If set to False, calls to
 90:      * queryStart() will simply be ignored.
 91:      *
 92:      * @var boolean
 93:      */
 94:     protected $_enabled = false;
 95: 
 96:     /**
 97:      * Stores the number of seconds to filter.  NULL if filtering by time is
 98:      * disabled.  If an integer is stored here, profiles whose elapsed time
 99:      * is less than this value in seconds will be unset from
100:      * the self::$_queryProfiles array.
101:      *
102:      * @var integer
103:      */
104:     protected $_filterElapsedSecs = null;
105: 
106:     /**
107:      * Logical OR of any of the filter constants.  NULL if filtering by query
108:      * type is disable.  If an integer is stored here, it is the logical OR of
109:      * any of the query type constants.  When the query ends, if it is not
110:      * one of the types specified, it will be unset from the
111:      * self::$_queryProfiles array.
112:      *
113:      * @var integer
114:      */
115:     protected $_filterTypes = null;
116: 
117:     /**
118:      * Class constructor.  The profiler is disabled by default unless it is
119:      * specifically enabled by passing in $enabled here or calling setEnabled().
120:      *
121:      * @param  boolean $enabled
122:      * @return void
123:      */
124:     public function __construct($enabled = false)
125:     {
126:         $this->setEnabled($enabled);
127:     }
128: 
129:     /**
130:      * Enable or disable the profiler.  If $enable is false, the profiler
131:      * is disabled and will not log any queries sent to it.
132:      *
133:      * @param  boolean $enable
134:      * @return Zend_Db_Profiler Provides a fluent interface
135:      */
136:     public function setEnabled($enable)
137:     {
138:         $this->_enabled = (boolean) $enable;
139: 
140:         return $this;
141:     }
142: 
143:     /**
144:      * Get the current state of enable.  If True is returned,
145:      * the profiler is enabled.
146:      *
147:      * @return boolean
148:      */
149:     public function getEnabled()
150:     {
151:         return $this->_enabled;
152:     }
153: 
154:     /**
155:      * Sets a minimum number of seconds for saving query profiles.  If this
156:      * is set, only those queries whose elapsed time is equal or greater than
157:      * $minimumSeconds will be saved.  To save all queries regardless of
158:      * elapsed time, set $minimumSeconds to null.
159:      *
160:      * @param  integer $minimumSeconds OPTIONAL
161:      * @return Zend_Db_Profiler Provides a fluent interface
162:      */
163:     public function setFilterElapsedSecs($minimumSeconds = null)
164:     {
165:         if (null === $minimumSeconds) {
166:             $this->_filterElapsedSecs = null;
167:         } else {
168:             $this->_filterElapsedSecs = (integer) $minimumSeconds;
169:         }
170: 
171:         return $this;
172:     }
173: 
174:     /**
175:      * Returns the minimum number of seconds for saving query profiles, or null if
176:      * query profiles are saved regardless of elapsed time.
177:      *
178:      * @return integer|null
179:      */
180:     public function getFilterElapsedSecs()
181:     {
182:         return $this->_filterElapsedSecs;
183:     }
184: 
185:     /**
186:      * Sets the types of query profiles to save.  Set $queryType to one of
187:      * the Zend_Db_Profiler::* constants to only save profiles for that type of
188:      * query.  To save more than one type, logical OR them together.  To
189:      * save all queries regardless of type, set $queryType to null.
190:      *
191:      * @param  integer $queryTypes OPTIONAL
192:      * @return Zend_Db_Profiler Provides a fluent interface
193:      */
194:     public function setFilterQueryType($queryTypes = null)
195:     {
196:         $this->_filterTypes = $queryTypes;
197: 
198:         return $this;
199:     }
200: 
201:     /**
202:      * Returns the types of query profiles saved, or null if queries are saved regardless
203:      * of their types.
204:      *
205:      * @return integer|null
206:      * @see    Zend_Db_Profiler::setFilterQueryType()
207:      */
208:     public function getFilterQueryType()
209:     {
210:         return $this->_filterTypes;
211:     }
212: 
213:     /**
214:      * Clears the history of any past query profiles.  This is relentless
215:      * and will even clear queries that were started and may not have
216:      * been marked as ended.
217:      *
218:      * @return Zend_Db_Profiler Provides a fluent interface
219:      */
220:     public function clear()
221:     {
222:         $this->_queryProfiles = array();
223: 
224:         return $this;
225:     }
226: 
227:     /**
228:      * @param  integer $queryId
229:      * @return integer or null
230:      */
231:     public function queryClone(Zend_Db_Profiler_Query $query)
232:     {
233:         $this->_queryProfiles[] = clone $query;
234: 
235:         end($this->_queryProfiles);
236: 
237:         return key($this->_queryProfiles);
238:     }
239: 
240:     /**
241:      * Starts a query.  Creates a new query profile object (Zend_Db_Profiler_Query)
242:      * and returns the "query profiler handle".  Run the query, then call
243:      * queryEnd() and pass it this handle to make the query as ended and
244:      * record the time.  If the profiler is not enabled, this takes no
245:      * action and immediately returns null.
246:      *
247:      * @param  string  $queryText   SQL statement
248:      * @param  integer $queryType   OPTIONAL Type of query, one of the Zend_Db_Profiler::* constants
249:      * @return integer|null
250:      */
251:     public function queryStart($queryText, $queryType = null)
252:     {
253:         if (!$this->_enabled) {
254:             return null;
255:         }
256: 
257:         // make sure we have a query type
258:         if (null === $queryType) {
259:             switch (strtolower(substr(ltrim($queryText), 0, 6))) {
260:                 case 'insert':
261:                     $queryType = self::INSERT;
262:                     break;
263:                 case 'update':
264:                     $queryType = self::UPDATE;
265:                     break;
266:                 case 'delete':
267:                     $queryType = self::DELETE;
268:                     break;
269:                 case 'select':
270:                     $queryType = self::SELECT;
271:                     break;
272:                 default:
273:                     $queryType = self::QUERY;
274:                     break;
275:             }
276:         }
277: 
278:         /**
279:          * @see Zend_Db_Profiler_Query
280:          */
281:         require_once 'Zend/Db/Profiler/Query.php';
282:         $this->_queryProfiles[] = new Zend_Db_Profiler_Query($queryText, $queryType);
283: 
284:         end($this->_queryProfiles);
285: 
286:         return key($this->_queryProfiles);
287:     }
288: 
289:     /**
290:      * Ends a query.  Pass it the handle that was returned by queryStart().
291:      * This will mark the query as ended and save the time.
292:      *
293:      * @param  integer $queryId
294:      * @throws Zend_Db_Profiler_Exception
295:      * @return void
296:      */
297:     public function queryEnd($queryId)
298:     {
299:         // Don't do anything if the Zend_Db_Profiler is not enabled.
300:         if (!$this->_enabled) {
301:             return self::IGNORED;
302:         }
303: 
304:         // Check for a valid query handle.
305:         if (!isset($this->_queryProfiles[$queryId])) {
306:             /**
307:              * @see Zend_Db_Profiler_Exception
308:              */
309:             require_once 'Zend/Db/Profiler/Exception.php';
310:             throw new Zend_Db_Profiler_Exception("Profiler has no query with handle '$queryId'.");
311:         }
312: 
313:         $qp = $this->_queryProfiles[$queryId];
314: 
315:         // Ensure that the query profile has not already ended
316:         if ($qp->hasEnded()) {
317:             /**
318:              * @see Zend_Db_Profiler_Exception
319:              */
320:             require_once 'Zend/Db/Profiler/Exception.php';
321:             throw new Zend_Db_Profiler_Exception("Query with profiler handle '$queryId' has already ended.");
322:         }
323: 
324:         // End the query profile so that the elapsed time can be calculated.
325:         $qp->end();
326: 
327:         /**
328:          * If filtering by elapsed time is enabled, only keep the profile if
329:          * it ran for the minimum time.
330:          */
331:         if (null !== $this->_filterElapsedSecs && $qp->getElapsedSecs() < $this->_filterElapsedSecs) {
332:             unset($this->_queryProfiles[$queryId]);
333:             return self::IGNORED;
334:         }
335: 
336:         /**
337:          * If filtering by query type is enabled, only keep the query if
338:          * it was one of the allowed types.
339:          */
340:         if (null !== $this->_filterTypes && !($qp->getQueryType() & $this->_filterTypes)) {
341:             unset($this->_queryProfiles[$queryId]);
342:             return self::IGNORED;
343:         }
344: 
345:         return self::STORED;
346:     }
347: 
348:     /**
349:      * Get a profile for a query.  Pass it the same handle that was returned
350:      * by queryStart() and it will return a Zend_Db_Profiler_Query object.
351:      *
352:      * @param  integer $queryId
353:      * @throws Zend_Db_Profiler_Exception
354:      * @return Zend_Db_Profiler_Query
355:      */
356:     public function getQueryProfile($queryId)
357:     {
358:         if (!array_key_exists($queryId, $this->_queryProfiles)) {
359:             /**
360:              * @see Zend_Db_Profiler_Exception
361:              */
362:             require_once 'Zend/Db/Profiler/Exception.php';
363:             throw new Zend_Db_Profiler_Exception("Query handle '$queryId' not found in profiler log.");
364:         }
365: 
366:         return $this->_queryProfiles[$queryId];
367:     }
368: 
369:     /**
370:      * Get an array of query profiles (Zend_Db_Profiler_Query objects).  If $queryType
371:      * is set to one of the Zend_Db_Profiler::* constants then only queries of that
372:      * type will be returned.  Normally, queries that have not yet ended will
373:      * not be returned unless $showUnfinished is set to True.  If no
374:      * queries were found, False is returned. The returned array is indexed by the query
375:      * profile handles.
376:      *
377:      * @param  integer $queryType
378:      * @param  boolean $showUnfinished
379:      * @return array|false
380:      */
381:     public function getQueryProfiles($queryType = null, $showUnfinished = false)
382:     {
383:         $queryProfiles = array();
384:         foreach ($this->_queryProfiles as $key => $qp) {
385:             if ($queryType === null) {
386:                 $condition = true;
387:             } else {
388:                 $condition = ($qp->getQueryType() & $queryType);
389:             }
390: 
391:             if (($qp->hasEnded() || $showUnfinished) && $condition) {
392:                 $queryProfiles[$key] = $qp;
393:             }
394:         }
395: 
396:         if (empty($queryProfiles)) {
397:             $queryProfiles = false;
398:         }
399: 
400:         return $queryProfiles;
401:     }
402: 
403:     /**
404:      * Get the total elapsed time (in seconds) of all of the profiled queries.
405:      * Only queries that have ended will be counted.  If $queryType is set to
406:      * one or more of the Zend_Db_Profiler::* constants, the elapsed time will be calculated
407:      * only for queries of the given type(s).
408:      *
409:      * @param  integer $queryType OPTIONAL
410:      * @return float
411:      */
412:     public function getTotalElapsedSecs($queryType = null)
413:     {
414:         $elapsedSecs = 0;
415:         foreach ($this->_queryProfiles as $key => $qp) {
416:             if (null === $queryType) {
417:                 $condition = true;
418:             } else {
419:                 $condition = ($qp->getQueryType() & $queryType);
420:             }
421:             if (($qp->hasEnded()) && $condition) {
422:                 $elapsedSecs += $qp->getElapsedSecs();
423:             }
424:         }
425:         return $elapsedSecs;
426:     }
427: 
428:     /**
429:      * Get the total number of queries that have been profiled.  Only queries that have ended will
430:      * be counted.  If $queryType is set to one of the Zend_Db_Profiler::* constants, only queries of
431:      * that type will be counted.
432:      *
433:      * @param  integer $queryType OPTIONAL
434:      * @return integer
435:      */
436:     public function getTotalNumQueries($queryType = null)
437:     {
438:         if (null === $queryType) {
439:             return count($this->_queryProfiles);
440:         }
441: 
442:         $numQueries = 0;
443:         foreach ($this->_queryProfiles as $qp) {
444:             if ($qp->hasEnded() && ($qp->getQueryType() & $queryType)) {
445:                 $numQueries++;
446:             }
447:         }
448: 
449:         return $numQueries;
450:     }
451: 
452:     /**
453:      * Get the Zend_Db_Profiler_Query object for the last query that was run, regardless if it has
454:      * ended or not.  If the query has not ended, its end time will be null.  If no queries have
455:      * been profiled, false is returned.
456:      *
457:      * @return Zend_Db_Profiler_Query|false
458:      */
459:     public function getLastQueryProfile()
460:     {
461:         if (empty($this->_queryProfiles)) {
462:             return false;
463:         }
464: 
465:         end($this->_queryProfiles);
466: 
467:         return current($this->_queryProfiles);
468:     }
469: 
470: }
471: 
472: 
Pry Framework API documentation generated by ApiGen 2.6.1