Doctrine_Db_* updates
This commit is contained in:
parent
21cde0e7b9
commit
fef149dd62
50
draft/DB.php
50
draft/DB.php
@ -37,12 +37,12 @@ class Doctrine_DB2 implements Countable, IteratorAggregate {
|
||||
/**
|
||||
* Any general database query that does not fit into the other constants.
|
||||
*/
|
||||
const QUERY = 2;
|
||||
const QUERY = 2;
|
||||
|
||||
/**
|
||||
* Adding new data to the database, such as SQL's INSERT.
|
||||
*/
|
||||
const INSERT = 4;
|
||||
const INSERT = 4;
|
||||
|
||||
/**
|
||||
* Updating existing information in the database, such as SQL's UPDATE.
|
||||
@ -123,6 +123,10 @@ class Doctrine_DB2 implements Countable, IteratorAggregate {
|
||||
$this->listener = new Doctrine_DB_EventListener();
|
||||
}
|
||||
|
||||
|
||||
public function nextQuerySequence() {
|
||||
return ++$this->querySequence;
|
||||
}
|
||||
/**
|
||||
* getQuerySequence
|
||||
*/
|
||||
@ -351,13 +355,13 @@ class Doctrine_DB2 implements Countable, IteratorAggregate {
|
||||
public function prepare($statement) {
|
||||
$this->connect();
|
||||
|
||||
$args = func_get_args();
|
||||
$event = new Doctrine_Db_Event($this, Doctrine_Db_Event::PREPARE, $statement);
|
||||
|
||||
$this->listener->onPrePrepare($this, $statement, $args);
|
||||
$this->listener->onPrePrepare($event);
|
||||
|
||||
$stmt = $this->dbh->prepare($statement);
|
||||
|
||||
$this->listener->onPrepare($this, $statement, $args, $this->querySequence);
|
||||
$this->listener->onPrepare($event);
|
||||
|
||||
$this->querySequence++;
|
||||
|
||||
@ -372,15 +376,17 @@ class Doctrine_DB2 implements Countable, IteratorAggregate {
|
||||
*/
|
||||
public function query($statement, array $params = array()) {
|
||||
$this->connect();
|
||||
|
||||
$this->listener->onPreQuery($this, $statement, $params);
|
||||
|
||||
if( ! empty($params))
|
||||
$event = new Doctrine_Db_Event($this, Doctrine_Db_Event::QUERY, $statement);
|
||||
|
||||
$this->listener->onPreQuery($event);
|
||||
|
||||
if( ! empty($params))
|
||||
$stmt = $this->dbh->query($statement)->execute($params);
|
||||
else
|
||||
$stmt = $this->dbh->query($statement);
|
||||
|
||||
$this->listener->onQuery($this, $statement, $params, $this->querySequence);
|
||||
$this->listener->onQuery($event);
|
||||
|
||||
$this->querySequence++;
|
||||
|
||||
@ -409,12 +415,14 @@ class Doctrine_DB2 implements Countable, IteratorAggregate {
|
||||
$this->connect();
|
||||
|
||||
$args = func_get_args();
|
||||
|
||||
$event = new Doctrine_Db_Event($this, Doctrine_Db_Event::EXEC, $statement);
|
||||
|
||||
$this->listener->onPreExec($this, $statement, $args);
|
||||
$this->listener->onPreExec($event);
|
||||
|
||||
$rows = $this->dbh->exec($statement);
|
||||
|
||||
$this->listener->onExec($this, $statement, $args);
|
||||
$this->listener->onExec($event);
|
||||
|
||||
return $rows;
|
||||
}
|
||||
@ -463,11 +471,13 @@ class Doctrine_DB2 implements Countable, IteratorAggregate {
|
||||
* @return boolean
|
||||
*/
|
||||
public function beginTransaction() {
|
||||
$this->listener->onPreBeginTransaction($this);
|
||||
$event = new Doctrine_Db_Event($this, Doctrine_Db_Event::BEGIN);
|
||||
|
||||
$this->listener->onPreBeginTransaction($event);
|
||||
|
||||
$return = $this->dbh->beginTransaction();
|
||||
|
||||
$this->listener->onBeginTransaction($this);
|
||||
$this->listener->onBeginTransaction($event);
|
||||
|
||||
return $return;
|
||||
}
|
||||
@ -477,11 +487,13 @@ class Doctrine_DB2 implements Countable, IteratorAggregate {
|
||||
* @return boolean
|
||||
*/
|
||||
public function commit() {
|
||||
$this->listener->onPreCommit($this);
|
||||
$event = new Doctrine_Db_Event($this, Doctrine_Db_Event::COMMIT);
|
||||
|
||||
$this->listener->onPreCommit($event);
|
||||
|
||||
$return = $this->dbh->commit();
|
||||
|
||||
$this->listener->onCommit($this);
|
||||
$this->listener->onCommit($event);
|
||||
|
||||
return $return;
|
||||
}
|
||||
@ -492,8 +504,14 @@ class Doctrine_DB2 implements Countable, IteratorAggregate {
|
||||
*/
|
||||
public function rollBack() {
|
||||
$this->connect();
|
||||
|
||||
|
||||
$event = new Doctrine_Db_Event($this, Doctrine_Db_Event::ROLLBACK);
|
||||
|
||||
$this->listener->onPreRollback($event);
|
||||
|
||||
$this->dbh->rollBack();
|
||||
|
||||
$this->listener->onRollback($event);
|
||||
}
|
||||
/**
|
||||
* getAttribute
|
||||
|
@ -82,14 +82,14 @@ class Doctrine_DataDict_Oracle extends Doctrine_DataDict {
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Maps a native array description of a field to a MDB2 datatype and length
|
||||
* Maps a native array description of a field to a doctrine datatype and length
|
||||
*
|
||||
* @param array $field native field description
|
||||
* @return array containing the various possible types, length, sign, fixed
|
||||
* @author Lukas Smith <smith@pooteeweet.org> (PEAR MDB2 library)
|
||||
* @throws Doctrine_DataDict_Oracle_Exception
|
||||
*/
|
||||
function mapNativeDatatype($field) {
|
||||
public function mapNativeDatatype(array $field) {
|
||||
$db_type = strtolower($field['type']);
|
||||
$type = array();
|
||||
$length = $unsigned = $fixed = null;
|
||||
|
@ -58,6 +58,8 @@ class Doctrine_DataDict_Pgsql extends Doctrine_DataDict {
|
||||
case 'string':
|
||||
case 'array':
|
||||
case 'object':
|
||||
case 'varchar':
|
||||
case 'char':
|
||||
$length = !empty($field['length'])
|
||||
? $field['length'] : $db->options['default_text_field_length'];
|
||||
|
||||
|
83
lib/Doctrine/Db/Event.php
Normal file
83
lib/Doctrine/Db/Event.php
Normal file
@ -0,0 +1,83 @@
|
||||
<?php
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information, see
|
||||
* <http://www.phpdoctrine.com>.
|
||||
*/
|
||||
/**
|
||||
* Doctrine_Db_Event
|
||||
*
|
||||
* @author Konsta Vesterinen
|
||||
* @license LGPL
|
||||
* @package Doctrine
|
||||
*/
|
||||
class Doctrine_Db_Event {
|
||||
const QUERY = 1;
|
||||
const EXEC = 2;
|
||||
const EXECUTE = 4;
|
||||
const PREPARE = 8;
|
||||
const BEGIN = 16;
|
||||
const COMMIT = 32;
|
||||
const ROLLBACK = 64;
|
||||
protected $invoker;
|
||||
|
||||
protected $query;
|
||||
|
||||
protected $type;
|
||||
|
||||
protected $startedMicrotime;
|
||||
|
||||
protected $endedMicrotime;
|
||||
|
||||
public function __construct($invoker, $type, $query = null) {
|
||||
$this->invoker = $invoker;
|
||||
$this->type = $type;
|
||||
$this->query = $query;
|
||||
}
|
||||
public function getQuery() {
|
||||
return $this->query;
|
||||
}
|
||||
public function getType() {
|
||||
return $this->type;
|
||||
}
|
||||
|
||||
public function start() {
|
||||
$this->startedMicrotime = microtime(true);
|
||||
}
|
||||
public function hasEnded() {
|
||||
return ($this->endedMicrotime != null);
|
||||
}
|
||||
public function end() {
|
||||
$this->endedMicrotime = microtime(true);
|
||||
}
|
||||
public function getInvoker() {
|
||||
return $this->invoker;
|
||||
}
|
||||
/**
|
||||
* Get the elapsed time (in seconds) that the query ran. If the query has
|
||||
* not yet ended, return false.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getElapsedSecs() {
|
||||
if (is_null($this->endedMicrotime))
|
||||
return false;
|
||||
|
||||
return ($this->endedMicrotime - $this->startedMicrotime);
|
||||
}
|
||||
|
||||
}
|
@ -26,24 +26,24 @@
|
||||
* @package Doctrine
|
||||
*/
|
||||
class Doctrine_Db_EventListener implements Doctrine_Db_EventListener_Interface {
|
||||
public function onPreQuery(Doctrine_DB2 $dbh, $statement, array $args) { }
|
||||
public function onQuery(Doctrine_DB2 $dbh, $statement, array $args, $queryId) { }
|
||||
public function onPreQuery(Doctrine_Db_Event $event) { }
|
||||
public function onQuery(Doctrine_Db_Event $event) { }
|
||||
|
||||
public function onPrePrepare(Doctrine_DB2 $dbh, $statement, array $args) { }
|
||||
public function onPrepare(Doctrine_DB2 $dbh, $statement, array $args, $queryId) { }
|
||||
public function onPrePrepare(Doctrine_Db_Event $event) { }
|
||||
public function onPrepare(Doctrine_Db_Event $event) { }
|
||||
|
||||
public function onPreCommit(Doctrine_DB2 $dbh) { }
|
||||
public function onCommit(Doctrine_DB2 $dbh) { }
|
||||
public function onPreCommit(Doctrine_Db_Event $event) { }
|
||||
public function onCommit(Doctrine_Db_Event $event) { }
|
||||
|
||||
public function onPreExec(Doctrine_DB2 $dbh, $statement, array $args) { }
|
||||
public function onExec(Doctrine_DB2 $dbh, $statement, array $args) { }
|
||||
public function onPreExec(Doctrine_Db_Event $event) { }
|
||||
public function onExec(Doctrine_Db_Event $event) { }
|
||||
|
||||
public function onPreRollBack(Doctrine_DB2 $dbh) { }
|
||||
public function onRollBack(Doctrine_DB2 $dbh) { }
|
||||
public function onPreRollBack(Doctrine_Db_Event $event) { }
|
||||
public function onRollBack(Doctrine_Db_Event $event) { }
|
||||
|
||||
public function onPreBeginTransaction(Doctrine_DB2 $dbh) { }
|
||||
public function onBeginTransaction(Doctrine_DB2 $dbh) { }
|
||||
public function onPreBeginTransaction(Doctrine_Db_Event $event) { }
|
||||
public function onBeginTransaction(Doctrine_Db_Event $event) { }
|
||||
|
||||
public function onPreExecute(Doctrine_Db_Statement $stmt, array $params) { }
|
||||
public function onExecute(Doctrine_Db_Statement $stmt, array $params) { }
|
||||
public function onPreExecute(Doctrine_Db_Event $event) { }
|
||||
public function onExecute(Doctrine_Db_Event $event) { }
|
||||
}
|
||||
|
@ -56,32 +56,32 @@ class Doctrine_Db_EventListener_Chain extends Doctrine_Access implements Doctrin
|
||||
|
||||
public function onQuery(Doctrine_DB2 $dbh, $statement, array $args, $queryId) {
|
||||
foreach($this->listeners as $listener) {
|
||||
$listener->onPreQuery($dbh, $args);
|
||||
$listener->onQuery($dbh, $args);
|
||||
}
|
||||
}
|
||||
public function onPreQuery(Doctrine_DB2 $dbh, $statement, array $args) {
|
||||
foreach($this->listeners as $listener) {
|
||||
$listener->onQuery($dbh, $args);
|
||||
$listener->onPreQuery($dbh, $args);
|
||||
}
|
||||
}
|
||||
|
||||
public function onPreExec(Doctrine_DB2 $dbh, array $args) {
|
||||
public function onPreExec(Doctrine_DB2 $dbh, $statement, array $args) {
|
||||
foreach($this->listeners as $listener) {
|
||||
$listener->onPreExec($dbh, $args);
|
||||
}
|
||||
}
|
||||
public function onExec(Doctrine_DB2 $dbh, array $args) {
|
||||
public function onExec(Doctrine_DB2 $dbh, $statement, array $args) {
|
||||
foreach($this->listeners as $listener) {
|
||||
$listener->onExec($dbh, $args);
|
||||
}
|
||||
}
|
||||
|
||||
public function onPrePrepare(Doctrine_DB2 $dbh, array $args) {
|
||||
public function onPrePrepare(Doctrine_DB2 $dbh, $statement, array $args) {
|
||||
foreach($this->listeners as $listener) {
|
||||
$listener->onPrePrepare($dbh, $args);
|
||||
}
|
||||
}
|
||||
public function onPrepare(Doctrine_DB2 $dbh, array $args) {
|
||||
public function onPrepare(Doctrine_DB2 $dbh, $statement, array $args, $queryId) {
|
||||
foreach($this->listeners as $listener) {
|
||||
$listener->onPrepare($dbh, $args);
|
||||
}
|
||||
|
@ -26,24 +26,24 @@
|
||||
* @package Doctrine
|
||||
*/
|
||||
interface Doctrine_Db_EventListener_Interface {
|
||||
public function onPreQuery(Doctrine_DB2 $dbh, $statement, array $args);
|
||||
public function onQuery(Doctrine_DB2 $dbh, $statement, array $args, $queryId);
|
||||
public function onPreQuery(Doctrine_Db_Event $event);
|
||||
public function onQuery(Doctrine_Db_Event $event);
|
||||
|
||||
public function onPrePrepare(Doctrine_DB2 $dbh, $statement, array $args);
|
||||
public function onPrepare(Doctrine_DB2 $dbh, $statement, array $args, $queryId);
|
||||
public function onPrePrepare(Doctrine_Db_Event $event);
|
||||
public function onPrepare(Doctrine_Db_Event $event);
|
||||
|
||||
public function onPreExec(Doctrine_DB2 $dbh, $statement, array $args);
|
||||
public function onExec(Doctrine_DB2 $dbh, $statement, array $args);
|
||||
public function onPreExec(Doctrine_Db_Event $event);
|
||||
public function onExec(Doctrine_Db_Event $event);
|
||||
|
||||
public function onPreCommit(Doctrine_DB2 $dbh);
|
||||
public function onCommit(Doctrine_DB2 $dbh);
|
||||
public function onPreCommit(Doctrine_Db_Event $event);
|
||||
public function onCommit(Doctrine_Db_Event $event);
|
||||
|
||||
public function onPreRollBack(Doctrine_DB2 $dbh);
|
||||
public function onRollBack(Doctrine_DB2 $dbh);
|
||||
public function onPreRollBack(Doctrine_Db_Event $event);
|
||||
public function onRollBack(Doctrine_Db_Event $event);
|
||||
|
||||
public function onPreBeginTransaction(Doctrine_DB2 $dbh);
|
||||
public function onBeginTransaction(Doctrine_DB2 $dbh);
|
||||
public function onPreBeginTransaction(Doctrine_Db_Event $event);
|
||||
public function onBeginTransaction(Doctrine_Db_Event $event);
|
||||
|
||||
public function onPreExecute(Doctrine_Db_Statement $stmt, array $params);
|
||||
public function onExecute(Doctrine_Db_Statement $stmt, array $params);
|
||||
public function onPreExecute(Doctrine_Db_Event $event);
|
||||
public function onExecute(Doctrine_Db_Event $event);
|
||||
}
|
||||
|
@ -25,226 +25,65 @@
|
||||
* @license LGPL
|
||||
* @package Doctrine
|
||||
*/
|
||||
class Doctrine_Db_Profiler extends Doctrine_Db_EventListener {
|
||||
public function onPreQuery(Doctrine_DB2 $dbh, $statement, array $args) {
|
||||
$this->queryStart($statement);
|
||||
}
|
||||
public function onQuery(Doctrine_DB2 $dbh, $statement, array $args, $queryId) {
|
||||
$this->queryEnd($queryId);
|
||||
}
|
||||
|
||||
public function onPrePrepare(Doctrine_DB2 $dbh, $statement, array $args) {
|
||||
$this->prepareTimes[$dbh->getQuerySequence()] = microtime(true);
|
||||
}
|
||||
public function onPrepare(Doctrine_DB2 $dbh, $statement, array $args, $queryId) {
|
||||
$this->prepareTimes[$queryId] = (microtime(true) - $this->prepareTimes[$queryId]);
|
||||
}
|
||||
|
||||
public function onPreCommit(Doctrine_DB2 $dbh) { }
|
||||
public function onCommit(Doctrine_DB2 $dbh) { }
|
||||
|
||||
public function onPreRollBack(Doctrine_DB2 $dbh) { }
|
||||
public function onRollBack(Doctrine_DB2 $dbh) { }
|
||||
|
||||
public function onPreBeginTransaction(Doctrine_DB2 $dbh) { }
|
||||
public function onBeginTransaction(Doctrine_DB2 $dbh) { }
|
||||
|
||||
public function onPreExecute(Doctrine_Db_Statement $stmt, array $params) {
|
||||
$this->queryStart($stmt->getQuery(), $stmt->getQuerySequence());
|
||||
}
|
||||
public function onExecute(Doctrine_Db_Statement $stmt, array $params) {
|
||||
$this->queryEnd($stmt->getQuerySequence());
|
||||
}
|
||||
class Doctrine_Db_Profiler implements Doctrine_Overloadable {
|
||||
/**
|
||||
* Array of Zend_Db_Profiler_Query objects.
|
||||
*
|
||||
* @var Zend_Db_Profiler_Query
|
||||
* @param array $listeners an array containing all availible listeners
|
||||
*/
|
||||
protected $_queryProfiles = array();
|
||||
|
||||
|
||||
protected $_prepareTimes = array();
|
||||
private $listeners = array('query',
|
||||
'prepare',
|
||||
'commit',
|
||||
'rollback',
|
||||
'begintransaction',
|
||||
'exec',
|
||||
'execute',
|
||||
);
|
||||
/**
|
||||
* 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
|
||||
* @param array $events an array containing all listened events
|
||||
*/
|
||||
protected $_filterElapsedSecs = null;
|
||||
|
||||
private $events = array();
|
||||
/**
|
||||
* 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.
|
||||
* method overloader
|
||||
* this method is used for invoking different listeners, for the full
|
||||
* list of availible listeners, see Doctrine_Db_EventListener
|
||||
*
|
||||
* @var integer
|
||||
* @param string $m the name of the method
|
||||
* @param array $a method arguments
|
||||
* @see Doctrine_Db_EventListener
|
||||
* @return void
|
||||
*/
|
||||
protected $_filterTypes = null;
|
||||
public function __call($m, $a) {
|
||||
// first argument should be an instance of Doctrine_Db_Event
|
||||
if( ! ($a[0] instanceof Doctrine_Db_Event))
|
||||
throw new Doctrine_Db_Profiler_Exception("Couldn't listen event. Event should be an instance of Doctrine_Db_Event.");
|
||||
|
||||
|
||||
/**
|
||||
* Start a query. Creates a new query profile object (Zend_Db_Profiler_Query)
|
||||
* 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 runs.
|
||||
*
|
||||
* @param string $queryText SQL statement
|
||||
* @param int $queryType Type of query, one of the Zend_Db_Profiler::* constants
|
||||
* @return mixed
|
||||
*/
|
||||
public function queryStart($queryText, $querySequence = -1) {
|
||||
$prepareTime = (isset($this->prepareTimes[$querySequence])) ? $this->prepareTimes[$querySequence] : null;
|
||||
|
||||
$this->_queryProfiles[] = new Doctrine_Db_Profiler_Query($queryText, $prepareTime);
|
||||
}
|
||||
/**
|
||||
* 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 Zend_Db_Profiler_Exception
|
||||
* @return boolean
|
||||
*/
|
||||
public function queryEnd($queryId = null) {
|
||||
|
||||
|
||||
// Check for a valid query handle.
|
||||
if($queryId === null)
|
||||
$qp = end($this->_queryProfiles);
|
||||
else
|
||||
$qp = $this->_queryProfiles[$queryId];
|
||||
|
||||
|
||||
if($qp === null || $qp->hasEnded()) {
|
||||
throw new Zend_Db_Profiler_Exception('Query with profiler handle "'
|
||||
. $queryId .'" has already ended.');
|
||||
// event methods should start with 'on'
|
||||
if(substr($m, 0, 2) !== 'on')
|
||||
throw new Doctrine_Db_Profiler_Exception("Couldn't invoke listener $m.");
|
||||
|
||||
if(substr($m, 2, 3) === 'Pre' && in_array(strtolower(substr($m, 3)), $this->listeners)) {
|
||||
// pre-event listener found
|
||||
$a[0]->start();
|
||||
} else {
|
||||
// after-event listener found
|
||||
$a[0]->end();
|
||||
}
|
||||
|
||||
// End the query profile so that the elapsed time can be calculated.
|
||||
$qp->end();
|
||||
|
||||
$this->events[] = $a[0];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get a profile for a query. Pass it the same handle that was returned
|
||||
* by queryStart() and it will return a Zend_Db_Profiler_Query object.
|
||||
* Get the Doctrine_Db_Event object for the last query that was run, regardless if it has
|
||||
* ended or not. If the event has not ended, it's end time will be Null.
|
||||
*
|
||||
* @param int $queryId
|
||||
* @throws Zend_Db_Profiler_Exception
|
||||
* @return Zend_Db_Profiler_Query
|
||||
* @return Doctrine_Db_Event
|
||||
*/
|
||||
public function getQueryProfile($queryId)
|
||||
{
|
||||
if (!array_key_exists($queryId, $this->_queryProfiles)) {
|
||||
throw new Zend_Db_Profiler_Exception("Query handle \"$queryId\" not found in profiler log.");
|
||||
}
|
||||
|
||||
return $this->_queryProfiles[$queryId];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get an array of query profiles (Zend_Db_Profiler_Query 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.
|
||||
*
|
||||
* @param string $queryType
|
||||
* @param bool $showUnfinished
|
||||
* @return mixed
|
||||
*/
|
||||
public function getQueryProfiles($queryType=null, $showUnfinished=false)
|
||||
{
|
||||
$queryProfiles = array();
|
||||
foreach ($this->_queryProfiles as $key=>$qp) {
|
||||
/* @var $qp Zend_Db_Profiler_Query */
|
||||
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 of the Zend_Db_Profiler::* constants, the elapsed time will be calculated
|
||||
* only for queries of that type.
|
||||
*
|
||||
* @param int $queryType
|
||||
* @return int
|
||||
*/
|
||||
public function getTotalElapsedSecs($queryType = null)
|
||||
{
|
||||
$elapsedSecs = 0;
|
||||
foreach ($this->_queryProfiles as $key=>$qp) {
|
||||
/* @var $qp Zend_Db_Profiler_Query */
|
||||
is_null($queryType)? $condition=true : $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 int $queryType
|
||||
* @return int
|
||||
*/
|
||||
public function getTotalNumQueries($queryType = null)
|
||||
{
|
||||
if (is_null($queryType)) {
|
||||
return sizeof($this->_queryProfiles);
|
||||
}
|
||||
|
||||
$numQueries = 0;
|
||||
foreach ($this->_queryProfiles as $qp) {
|
||||
/* @var $qp Zend_Db_Profiler_Query */
|
||||
is_null($queryType)? $condition=true : $condition=($qp->getQueryType() & $queryType);
|
||||
if ($qp->hasEnded() && $condition) {
|
||||
$numQueries++;
|
||||
}
|
||||
}
|
||||
return $numQueries;
|
||||
}
|
||||
|
||||
public function pop() {
|
||||
return array_pop($this->_queryProfiles);
|
||||
}
|
||||
/**
|
||||
* Get the Zend_Db_Profiler_Query object for the last query that was run, regardless if it has
|
||||
* ended or not. If the query has not ended, it's end time will be Null.
|
||||
*
|
||||
* @return Zend_Db_Profiler_Query
|
||||
*/
|
||||
public function lastQuery() {
|
||||
if (empty($this->_queryProfiles)) {
|
||||
public function lastEvent() {
|
||||
if (empty($this->events)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
end($this->_queryProfiles);
|
||||
return current($this->_queryProfiles);
|
||||
end($this->events);
|
||||
return current($this->events);
|
||||
}
|
||||
}
|
||||
|
29
lib/Doctrine/Db/Profiler/Exception.php
Normal file
29
lib/Doctrine/Db/Profiler/Exception.php
Normal file
@ -0,0 +1,29 @@
|
||||
<?php
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information, see
|
||||
* <http://www.phpdoctrine.com>.
|
||||
*/
|
||||
Doctrine::autoload('Doctrine_Db_Exception');
|
||||
/**
|
||||
* Doctrine_Db_Exception
|
||||
*
|
||||
* @author Konsta Vesterinen
|
||||
* @license LGPL
|
||||
* @package Doctrine
|
||||
*/
|
||||
class Doctrine_Db_Profiler_Exception extends Doctrine_Db_Exception { }
|
@ -58,14 +58,17 @@ class Doctrine_Db_Profiler_Query {
|
||||
*
|
||||
* @param string $query
|
||||
* @param int $queryType
|
||||
* @return bool
|
||||
*/
|
||||
public function __construct($query, $prepareTime = null)
|
||||
{
|
||||
public function __construct($query, $prepareTime = null) {
|
||||
$this->query = $query;
|
||||
$this->prepareTime = $prepareTime;
|
||||
$this->startedMicrotime = microtime(true);
|
||||
return true;
|
||||
if($prepareTime !== null) {
|
||||
$this->prepareTime = $prepareTime;
|
||||
} else {
|
||||
$this->startedMicrotime = microtime(true);
|
||||
}
|
||||
}
|
||||
public function start() {
|
||||
$this->startedMicrotime = microtime(true);
|
||||
}
|
||||
/**
|
||||
* The query has ended. Record the time so that the elapsed time can be determined later.
|
||||
|
@ -29,26 +29,43 @@ class Doctrine_Db_Statement extends PDOStatement {
|
||||
protected $dbh;
|
||||
|
||||
protected $querySequence;
|
||||
|
||||
protected $baseSequence;
|
||||
|
||||
protected $executed = false;
|
||||
|
||||
protected function __construct($dbh) {
|
||||
$this->dbh = $dbh;
|
||||
$this->querySequence = $this->dbh->getQuerySequence();
|
||||
$this->baseSequence = $this->querySequence = $this->dbh->getQuerySequence();
|
||||
}
|
||||
|
||||
|
||||
public function getQuerySequence() {
|
||||
return $this->querySequence;
|
||||
}
|
||||
public function getBaseSequence() {
|
||||
return $this->baseSequence;
|
||||
}
|
||||
public function getQuery() {
|
||||
return $this->queryString;
|
||||
}
|
||||
public function isExecuted($executed = null) {
|
||||
if($executed === null)
|
||||
return $this->executed;
|
||||
|
||||
$this->executed = (bool) $executed;
|
||||
}
|
||||
|
||||
public function execute(array $params) {
|
||||
$this->dbh->getListener()->onPreExecute($this, $params);
|
||||
|
||||
$event = new Doctrine_Db_Event($this, Doctrine_Db_Event::EXECUTE, $this->queryString);
|
||||
|
||||
$this->dbh->getListener()->onPreExecute($event);
|
||||
|
||||
$ret = parent::execute($params);
|
||||
|
||||
$this->dbh->getListener()->onExecute($this, $params);
|
||||
|
||||
|
||||
$this->dbh->getListener()->onExecute($event);
|
||||
|
||||
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
|
@ -15,51 +15,56 @@ class Doctrine_Db_Profiler_TestCase extends Doctrine_UnitTestCase {
|
||||
|
||||
$this->dbh->query('CREATE TABLE test (id INT)');
|
||||
|
||||
$this->assertEqual($this->profiler->lastQuery()->getQuery(), 'CREATE TABLE test (id INT)');
|
||||
$this->assertTrue($this->profiler->lastQuery()->hasEnded());
|
||||
$this->assertTrue(is_numeric($this->profiler->lastQuery()->getElapsedSecs()));
|
||||
$this->assertEqual($this->profiler->lastEvent()->getQuery(), 'CREATE TABLE test (id INT)');
|
||||
$this->assertTrue($this->profiler->lastEvent()->hasEnded());
|
||||
$this->assertEqual($this->profiler->lastEvent()->getType(), Doctrine_Db_Event::QUERY);
|
||||
$this->assertTrue(is_numeric($this->profiler->lastEvent()->getElapsedSecs()));
|
||||
|
||||
$this->assertEqual($this->dbh->count(), 1);
|
||||
}
|
||||
public function testPrepareAndExecute() {
|
||||
|
||||
$stmt = $this->dbh->prepare('INSERT INTO test (id) VALUES (?)');
|
||||
$stmt = $this->dbh->prepare('INSERT INTO test (id) VALUES (?)');
|
||||
$event = $this->profiler->lastEvent();
|
||||
|
||||
$this->assertEqual($this->profiler->lastQuery()->getQuery(), 'INSERT INTO test (id) VALUES (?)');
|
||||
$this->assertFalse($this->profiler->lastQuery()->hasEnded());
|
||||
$this->assertTrue(is_numeric($this->profiler->lastQuery()->getElapsedSecs()));
|
||||
$this->assertEqual($event->getQuery(), 'INSERT INTO test (id) VALUES (?)');
|
||||
$this->assertTrue($this->profiler->lastEvent()->hasEnded());
|
||||
$this->assertEqual($this->profiler->lastEvent()->getType(), Doctrine_Db_Event::PREPARE);
|
||||
$this->assertTrue(is_numeric($this->profiler->lastEvent()->getElapsedSecs()));
|
||||
|
||||
$stmt->execute(array(1));
|
||||
|
||||
$this->assertEqual($this->profiler->lastQuery()->getQuery(), 'INSERT INTO test (id) VALUES (?)');
|
||||
$this->assertTrue($this->profiler->lastQuery()->hasEnded());
|
||||
$this->assertTrue(is_numeric($this->profiler->lastQuery()->getElapsedSecs()));
|
||||
$this->assertEqual($this->profiler->lastEvent()->getQuery(), 'INSERT INTO test (id) VALUES (?)');
|
||||
$this->assertTrue($this->profiler->lastEvent()->hasEnded());
|
||||
$this->assertEqual($this->profiler->lastEvent()->getType(), Doctrine_Db_Event::EXECUTE);
|
||||
$this->assertTrue(is_numeric($this->profiler->lastEvent()->getElapsedSecs()));
|
||||
|
||||
$this->assertEqual($this->dbh->count(), 2);
|
||||
}
|
||||
|
||||
public function testMultiplePrepareAndExecute() {
|
||||
|
||||
$stmt = $this->dbh->prepare('INSERT INTO test (id) VALUES (?)');
|
||||
$this->assertEqual($this->profiler->lastQuery()->getQuery(), 'INSERT INTO test (id) VALUES (?)');
|
||||
$this->assertFalse($this->profiler->lastQuery()->hasEnded());
|
||||
$this->assertTrue(is_numeric($this->profiler->lastQuery()->getElapsedSecs()));
|
||||
$this->assertEqual($this->profiler->lastEvent()->getQuery(), 'INSERT INTO test (id) VALUES (?)');
|
||||
$this->assertTrue($this->profiler->lastEvent()->hasEnded());
|
||||
$this->assertEqual($this->profiler->lastEvent()->getType(), Doctrine_Db_Event::PREPARE);
|
||||
$this->assertTrue(is_numeric($this->profiler->lastEvent()->getElapsedSecs()));
|
||||
|
||||
$stmt2 = $this->dbh->prepare('INSERT INTO test (id) VALUES (?)');
|
||||
$this->assertEqual($this->profiler->lastQuery()->getQuery(), 'INSERT INTO test (id) VALUES (?)');
|
||||
$this->assertFalse($this->profiler->lastQuery()->hasEnded());
|
||||
$this->assertTrue(is_numeric($this->profiler->lastQuery()->getElapsedSecs()));
|
||||
$this->assertEqual($this->profiler->lastEvent()->getQuery(), 'INSERT INTO test (id) VALUES (?)');
|
||||
$this->assertTrue($this->profiler->lastEvent()->hasEnded());
|
||||
$this->assertEqual($this->profiler->lastEvent()->getType(), Doctrine_Db_Event::PREPARE);
|
||||
$this->assertTrue(is_numeric($this->profiler->lastEvent()->getElapsedSecs()));
|
||||
|
||||
$stmt->execute(array(1));
|
||||
$stmt2->execute(array(1));
|
||||
|
||||
$this->assertEqual($this->profiler->lastQuery()->getQuery(), 'INSERT INTO test (id) VALUES (?)');
|
||||
$this->assertTrue($this->profiler->lastQuery()->hasEnded());
|
||||
$this->assertTrue(is_numeric($this->profiler->lastQuery()->getElapsedSecs()));
|
||||
$this->assertEqual($this->profiler->lastEvent()->getQuery(), 'INSERT INTO test (id) VALUES (?)');
|
||||
$this->assertTrue($this->profiler->lastEvent()->hasEnded());
|
||||
$this->assertEqual($this->profiler->lastEvent()->getType(), Doctrine_Db_Event::EXECUTE);
|
||||
$this->assertTrue(is_numeric($this->profiler->lastEvent()->getElapsedSecs()));
|
||||
|
||||
$this->assertEqual($this->dbh->count(), 4);
|
||||
}
|
||||
/**
|
||||
public function testExecuteStatementMultipleTimes() {
|
||||
try {
|
||||
$stmt = $this->dbh->prepare('INSERT INTO test (id) VALUES (?)');
|
||||
@ -67,15 +72,66 @@ class Doctrine_Db_Profiler_TestCase extends Doctrine_UnitTestCase {
|
||||
$stmt->execute(array(1));
|
||||
$this->pass();
|
||||
} catch(Doctrine_Db_Exception $e) {
|
||||
$this->fail();
|
||||
}
|
||||
$this->assertEqual($this->profiler->lastQuery()->getQuery(), 'INSERT INTO test (id) VALUES (?)');
|
||||
$this->assertTrue($this->profiler->lastQuery()->hasEnded());
|
||||
$this->assertTrue(is_numeric($this->profiler->lastQuery()->getElapsedSecs()));
|
||||
|
||||
$this->assertEqual($this->profiler->lastQuery()->getQuery(), 'INSERT INTO test (id) VALUES (?)');
|
||||
$this->assertTrue($this->profiler->lastQuery()->hasEnded());
|
||||
$this->assertTrue(is_numeric($this->profiler->lastQuery()->getElapsedSecs()));
|
||||
} */
|
||||
$this->fail($e->__toString());
|
||||
}
|
||||
$this->assertEqual($this->profiler->lastEvent()->getQuery(), 'INSERT INTO test (id) VALUES (?)');
|
||||
$this->assertTrue($this->profiler->lastEvent()->hasEnded());
|
||||
$this->assertEqual($this->profiler->lastEvent()->getType(), Doctrine_Db_Event::EXECUTE);
|
||||
$this->assertTrue(is_numeric($this->profiler->lastEvent()->getElapsedSecs()));
|
||||
|
||||
$this->assertEqual($this->profiler->lastEvent()->getQuery(), 'INSERT INTO test (id) VALUES (?)');
|
||||
$this->assertTrue($this->profiler->lastEvent()->hasEnded());
|
||||
$this->assertEqual($this->profiler->lastEvent()->getType(), Doctrine_Db_Event::EXECUTE);
|
||||
$this->assertTrue(is_numeric($this->profiler->lastEvent()->getElapsedSecs()));
|
||||
}
|
||||
public function testTransactionRollback() {
|
||||
try {
|
||||
$this->dbh->beginTransaction();
|
||||
$this->pass();
|
||||
} catch(Doctrine_Db_Exception $e) {
|
||||
$this->fail($e->__toString());
|
||||
}
|
||||
$this->assertEqual($this->profiler->lastEvent()->getQuery(), null);
|
||||
$this->assertTrue($this->profiler->lastEvent()->hasEnded());
|
||||
$this->assertEqual($this->profiler->lastEvent()->getType(), Doctrine_Db_Event::BEGIN);
|
||||
$this->assertTrue(is_numeric($this->profiler->lastEvent()->getElapsedSecs()));
|
||||
|
||||
try {
|
||||
$this->dbh->rollback();
|
||||
$this->pass();
|
||||
} catch(Doctrine_Db_Exception $e) {
|
||||
$this->fail($e->__toString());
|
||||
}
|
||||
|
||||
$this->assertEqual($this->profiler->lastEvent()->getQuery(), null);
|
||||
$this->assertTrue($this->profiler->lastEvent()->hasEnded());
|
||||
$this->assertEqual($this->profiler->lastEvent()->getType(), Doctrine_Db_Event::ROLLBACK);
|
||||
$this->assertTrue(is_numeric($this->profiler->lastEvent()->getElapsedSecs()));
|
||||
}
|
||||
public function testTransactionCommit() {
|
||||
try {
|
||||
$this->dbh->beginTransaction();
|
||||
$this->pass();
|
||||
} catch(Doctrine_Db_Exception $e) {
|
||||
$this->fail($e->__toString());
|
||||
}
|
||||
$this->assertEqual($this->profiler->lastEvent()->getQuery(), null);
|
||||
$this->assertTrue($this->profiler->lastEvent()->hasEnded());
|
||||
$this->assertEqual($this->profiler->lastEvent()->getType(), Doctrine_Db_Event::BEGIN);
|
||||
$this->assertTrue(is_numeric($this->profiler->lastEvent()->getElapsedSecs()));
|
||||
|
||||
try {
|
||||
$this->dbh->commit();
|
||||
$this->pass();
|
||||
} catch(Doctrine_Db_Exception $e) {
|
||||
$this->fail($e->__toString());
|
||||
}
|
||||
|
||||
$this->assertEqual($this->profiler->lastEvent()->getQuery(), null);
|
||||
$this->assertTrue($this->profiler->lastEvent()->hasEnded());
|
||||
$this->assertEqual($this->profiler->lastEvent()->getType(), Doctrine_Db_Event::COMMIT);
|
||||
$this->assertTrue(is_numeric($this->profiler->lastEvent()->getElapsedSecs()));
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
@ -68,9 +68,9 @@ print '<pre>';
|
||||
$test = new GroupTest('Doctrine Framework Unit Tests');
|
||||
|
||||
|
||||
//$test->addTestCase(new Doctrine_Db_Profiler_TestCase());
|
||||
|
||||
//$test->addTestCase(new Doctrine_DB_TestCase());
|
||||
$test->addTestCase(new Doctrine_Db_Profiler_TestCase());
|
||||
/**
|
||||
$test->addTestCase(new Doctrine_Db_TestCase());
|
||||
|
||||
$test->addTestCase(new Doctrine_Query_MultiJoin_TestCase());
|
||||
|
||||
@ -154,14 +154,15 @@ $test->addTestCase(new Doctrine_Query_Where_TestCase());
|
||||
|
||||
$test->addTestCase(new Doctrine_Query_From_TestCase());
|
||||
|
||||
$test->addTestCase(new Doctrine_Query_Select_TestCase());
|
||||
|
||||
$test->addTestCase(new Doctrine_Query_Delete_TestCase());
|
||||
|
||||
$test->addTestCase(new Doctrine_Query_Update_TestCase());
|
||||
|
||||
$test->addTestCase(new Doctrine_Query_Limit_TestCase());
|
||||
|
||||
*/
|
||||
$test->addTestCase(new Doctrine_Query_Select_TestCase());
|
||||
|
||||
|
||||
|
||||
//$test->addTestCase(new Doctrine_Cache_FileTestCase());
|
||||
|
Loading…
x
Reference in New Issue
Block a user