Small reorganizations, improvements and progress.
This commit is contained in:
parent
2eb4a16dd4
commit
9dcab5ee63
@ -1,7 +1,22 @@
|
||||
<?php
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
/*
|
||||
* $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.doctrine-project.org>.
|
||||
*/
|
||||
|
||||
namespace Doctrine\Common\Collections;
|
||||
@ -12,10 +27,11 @@ use \ArrayAccess;
|
||||
use \ArrayIterator;
|
||||
|
||||
/**
|
||||
* A Collection is a wrapper around a php array and just like a php array a
|
||||
* collection instance can be a list, a set or a map, depending on how it is used.
|
||||
* A Collection is a thin wrapper around a php array. Think of it as an OO version
|
||||
* of a plain array.
|
||||
*
|
||||
* @author robo
|
||||
* @since 2.0
|
||||
*/
|
||||
class Collection implements Countable, IteratorAggregate, ArrayAccess
|
||||
{
|
||||
@ -25,7 +41,7 @@ class Collection implements Countable, IteratorAggregate, ArrayAccess
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $_data = array();
|
||||
protected $_elements = array();
|
||||
|
||||
/**
|
||||
*
|
||||
@ -33,7 +49,7 @@ class Collection implements Countable, IteratorAggregate, ArrayAccess
|
||||
*/
|
||||
public function __construct(array $elements = array())
|
||||
{
|
||||
$this->_data = $elements;
|
||||
$this->_elements = $elements;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -43,49 +59,49 @@ class Collection implements Countable, IteratorAggregate, ArrayAccess
|
||||
*/
|
||||
public function unwrap()
|
||||
{
|
||||
return $this->_data;
|
||||
return $this->_elements;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the first entry in the collection
|
||||
* Gets the first element in the collection.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function first()
|
||||
{
|
||||
return reset($this->_data);
|
||||
return reset($this->_elements);
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the last record in the collection
|
||||
* Gets the last element in the collection.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function last()
|
||||
{
|
||||
return end($this->_data);
|
||||
return end($this->_elements);
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the current key
|
||||
* Gets the current key.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function key()
|
||||
{
|
||||
return key($this->_data);
|
||||
return key($this->_elements);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes an entry with a specific key from the collection.
|
||||
* Removes an element with a specific key from the collection.
|
||||
*
|
||||
* @param mixed $key
|
||||
* @return mixed
|
||||
*/
|
||||
public function remove($key)
|
||||
{
|
||||
$removed = $this->_data[$key];
|
||||
unset($this->_data[$key]);
|
||||
$removed = $this->_elements[$key];
|
||||
unset($this->_elements[$key]);
|
||||
return $removed;
|
||||
}
|
||||
|
||||
@ -97,9 +113,9 @@ class Collection implements Countable, IteratorAggregate, ArrayAccess
|
||||
*/
|
||||
public function removeElement($element)
|
||||
{
|
||||
$key = array_search($element, $this->_data, true);
|
||||
$key = array_search($element, $this->_elements, true);
|
||||
if ($key !== false) {
|
||||
unset($this->_data[$key]);
|
||||
unset($this->_elements[$key]);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@ -169,7 +185,7 @@ class Collection implements Countable, IteratorAggregate, ArrayAccess
|
||||
*/
|
||||
public function containsKey($key)
|
||||
{
|
||||
return isset($this->_data[$key]);
|
||||
return isset($this->_elements[$key]);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -184,24 +200,23 @@ class Collection implements Countable, IteratorAggregate, ArrayAccess
|
||||
*/
|
||||
public function contains($element)
|
||||
{
|
||||
return in_array($element, $this->_data, true);
|
||||
return in_array($element, $this->_elements, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests for the existance of an element that satisfies the given predicate.
|
||||
*
|
||||
* @param function $func
|
||||
* @param Closure $p The predicate.
|
||||
* @return boolean TRUE if the predicate is TRUE for at least one element, FALSE otherwise.
|
||||
*/
|
||||
public function exists(Closure $func) {
|
||||
foreach ($this->_data as $key => $element)
|
||||
if ($func($key, $element))
|
||||
return true;
|
||||
public function exists(Closure $p) {
|
||||
foreach ($this->_elements as $key => $element)
|
||||
if ($p($key, $element)) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enter description here...
|
||||
* TODO
|
||||
*
|
||||
* @param unknown_type $otherColl
|
||||
* @todo Impl
|
||||
@ -222,7 +237,7 @@ class Collection implements Countable, IteratorAggregate, ArrayAccess
|
||||
*/
|
||||
public function search($element)
|
||||
{
|
||||
return array_search($element, $this->_data, true);
|
||||
return array_search($element, $this->_elements, true);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -233,20 +248,20 @@ class Collection implements Countable, IteratorAggregate, ArrayAccess
|
||||
*/
|
||||
public function get($key)
|
||||
{
|
||||
if (isset($this->_data[$key])) {
|
||||
return $this->_data[$key];
|
||||
if (isset($this->_elements[$key])) {
|
||||
return $this->_elements[$key];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all keys/indexes.
|
||||
* Gets all keys/indexes of the collection elements.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getKeys()
|
||||
{
|
||||
return array_keys($this->_data);
|
||||
return array_keys($this->_elements);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -256,7 +271,7 @@ class Collection implements Countable, IteratorAggregate, ArrayAccess
|
||||
*/
|
||||
public function getElements()
|
||||
{
|
||||
return array_values($this->_data);
|
||||
return array_values($this->_elements);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -268,7 +283,7 @@ class Collection implements Countable, IteratorAggregate, ArrayAccess
|
||||
*/
|
||||
public function count()
|
||||
{
|
||||
return count($this->_data);
|
||||
return count($this->_elements);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -277,24 +292,23 @@ class Collection implements Countable, IteratorAggregate, ArrayAccess
|
||||
* When the collection is a Map this is like put(key,value)/add(key,value).
|
||||
* When the collection is a List this is like add(position,value).
|
||||
*
|
||||
* @param integer $key
|
||||
* @param mixed $key
|
||||
* @param mixed $value
|
||||
*/
|
||||
public function set($key, $value)
|
||||
{
|
||||
$this->_data[$key] = $value;
|
||||
$this->_elements[$key] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an element to the collection.
|
||||
*
|
||||
* @param mixed $value
|
||||
* @param string $key
|
||||
* @return boolean Always returns TRUE.
|
||||
* @return boolean Always TRUE.
|
||||
*/
|
||||
public function add($value)
|
||||
{
|
||||
$this->_data[] = $value;
|
||||
$this->_elements[] = $value;
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -317,45 +331,80 @@ class Collection implements Countable, IteratorAggregate, ArrayAccess
|
||||
public function isEmpty()
|
||||
{
|
||||
// Note: Little "trick". Empty arrays evaluate to FALSE. No need to count().
|
||||
return ! (bool)$this->_data;
|
||||
return ! (bool)$this->_elements;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an iterator that enables foreach() iteration over the elements in
|
||||
* the collection.
|
||||
* Gets an iterator for iterating over the elements in the collection.
|
||||
*
|
||||
* @return ArrayIterator
|
||||
*/
|
||||
public function getIterator()
|
||||
{
|
||||
$data = $this->_data;
|
||||
return new ArrayIterator($data);
|
||||
return new ArrayIterator($this->_elements);
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies the given function to each element in the collection and returns
|
||||
* a new collection with the modified values.
|
||||
* a new collection with the elements returned by the function.
|
||||
*
|
||||
* @param function $func
|
||||
* @param Closure $func
|
||||
*/
|
||||
public function map(Closure $func)
|
||||
{
|
||||
return new Collection(array_map($func, $this->_data));
|
||||
return new Collection(array_map($func, $this->_elements));
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies the given function to each element in the collection and returns
|
||||
* a new collection with the new values.
|
||||
* Returns all the elements of this collection that satisfy the predicate p.
|
||||
* The order of the elements is preserved.
|
||||
*
|
||||
* @param function $func
|
||||
* @param Closure $p The predicate used for filtering.
|
||||
* @return Collection A collection with the results of the filter operation.
|
||||
*/
|
||||
public function filter(Closure $func)
|
||||
public function filter(Closure $p)
|
||||
{
|
||||
return new Collection(array_filter($this->_data, $func));
|
||||
return new Collection(array_filter($this->_elements, $p));
|
||||
}
|
||||
|
||||
/**
|
||||
* returns a string representation of this object
|
||||
* Applies the given predicate p to all elements of this collection,
|
||||
* returning true, if the predicate yields true for all elements.
|
||||
*
|
||||
* @param Closure $p The predicate.
|
||||
* @return boolean TRUE, if the predicate yields TRUE for all elements, FALSE otherwise.
|
||||
*/
|
||||
public function forall(Closure $p)
|
||||
{
|
||||
foreach ($this->_elements as $key => $element)
|
||||
if ( ! $p($key, $element)) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Partitions this collection in two collections according to a predicate.
|
||||
* Keys are preserved in the resulting collections.
|
||||
*
|
||||
* @param Closure $p The predicate on which to partition.
|
||||
* @return array An array with two elements. The first element contains the collection
|
||||
* of elements where the predicate returned TRUE, the second element
|
||||
* contains the collection of elements where the predicate returned FALSE.
|
||||
*/
|
||||
public function partition(Closure $p)
|
||||
{
|
||||
$coll1 = $coll2 = array();
|
||||
foreach ($this->_elements as $key => $element) {
|
||||
if ($p($key, $element)) {
|
||||
$coll1[$key] = $element;
|
||||
} else {
|
||||
$coll2[$key] = $element;
|
||||
}
|
||||
}
|
||||
return array(new Collection($coll1), new Collection($coll2));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string representation of this object.
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
@ -364,12 +413,10 @@ class Collection implements Countable, IteratorAggregate, ArrayAccess
|
||||
|
||||
/**
|
||||
* Clears the collection.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function clear()
|
||||
{
|
||||
$this->_data = array();
|
||||
$this->_elements = array();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -16,60 +16,51 @@
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information, see
|
||||
* <http://www.phpdoctrine.org>.
|
||||
* <http://www.doctrine-project.org>.
|
||||
*/
|
||||
|
||||
namespace Doctrine\Common\Events;
|
||||
namespace Doctrine\Common;
|
||||
|
||||
/**
|
||||
* Doctrine_Event
|
||||
* EventArgs is the base class for classes containing event data.
|
||||
*
|
||||
* This class contains no event data and cannot be instantiated.
|
||||
* It is used by events that do not pass state information to an event handler
|
||||
* when an event is raised. The single empty EventArgs instance can be obtained
|
||||
* through {@link getEmptyInstance()}.
|
||||
*
|
||||
* @author Konsta Vesterinen <kvesteri@cc.hut.fi>
|
||||
* @author Roman Borschel
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.phpdoctrine.org
|
||||
* @link www.doctrine-project.org
|
||||
* @since 2.0
|
||||
* @version $Revision$
|
||||
*/
|
||||
class Event
|
||||
class EventArgs
|
||||
{
|
||||
/* Event callback constants */
|
||||
const preDelete = 'preDelete';
|
||||
const postDelete = 'postDelete';
|
||||
//...more
|
||||
private static $_emptyEventArgsInstance;
|
||||
private $_defaultPrevented;
|
||||
|
||||
protected $_type;
|
||||
protected $_target;
|
||||
protected $_defaultPrevented;
|
||||
|
||||
|
||||
public function __construct($type, $target = null)
|
||||
protected function __construct()
|
||||
{
|
||||
$this->_type = $type;
|
||||
$this->_target = $target;
|
||||
$this->_defaultPrevented = false;
|
||||
}
|
||||
|
||||
|
||||
public function getType()
|
||||
{
|
||||
return $this->_type;
|
||||
}
|
||||
|
||||
|
||||
public function preventDefault()
|
||||
{
|
||||
$this->_defaultPrevented = true;
|
||||
}
|
||||
|
||||
|
||||
public function getDefaultPrevented()
|
||||
{
|
||||
return $this->_defaultPrevented;
|
||||
}
|
||||
|
||||
|
||||
public function getTarget()
|
||||
public static function getEmptyInstance()
|
||||
{
|
||||
return $this->_target;
|
||||
if ( ! self::$_emptyEventArgsInstance) {
|
||||
self::$_emptyEventArgsInstance = new EventArgs;
|
||||
}
|
||||
return self::$_emptyEventArgsInstance;
|
||||
}
|
||||
}
|
@ -16,7 +16,7 @@
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information, see
|
||||
* <http://www.phpdoctrine.org>.
|
||||
* <http://www.doctrine-project.org>.
|
||||
*/
|
||||
|
||||
namespace Doctrine\Common;
|
||||
@ -45,20 +45,20 @@ class EventManager
|
||||
/**
|
||||
* Dispatches an event to all registered listeners.
|
||||
*
|
||||
* @param string|Event $event The name of the event or the event object.
|
||||
* @param string $eventName The name of the event to dispatch. The name of the event is
|
||||
* the name of the method that is invoked on listeners.
|
||||
* @param EventArgs $eventArgs The event arguments to pass to the event handlers/listeners.
|
||||
* If not supplied, the single empty EventArgs instance is used.
|
||||
* @return boolean
|
||||
*/
|
||||
public function dispatchEvent($event)
|
||||
public function dispatchEvent($eventName, EventArgs $eventArgs = null)
|
||||
{
|
||||
$argIsCallback = is_string($event);
|
||||
$callback = $argIsCallback ? $event : $event->getType();
|
||||
|
||||
if (isset($this->_listeners[$callback])) {
|
||||
$event = $argIsCallback ? new Event($event) : $event;
|
||||
foreach ($this->_listeners[$callback] as $listener) {
|
||||
$listener->$callback($event);
|
||||
if (isset($this->_listeners[$eventName])) {
|
||||
$eventArgs = is_null($eventArgs) ? EventArgs::getEmptyInstance() : $eventArgs;
|
||||
foreach ($this->_listeners[$eventName] as $listener) {
|
||||
$listener->$eventName($eventArgs);
|
||||
}
|
||||
return ! $event->getDefaultPrevented();
|
||||
return ! $eventArgs->getDefaultPrevented();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -95,7 +95,7 @@ class EventManager
|
||||
{
|
||||
// TODO: maybe check for duplicate registrations?
|
||||
foreach ((array)$events as $event) {
|
||||
$this->_listeners[$event] = $listener;
|
||||
$this->_listeners[$event][] = $listener;
|
||||
}
|
||||
}
|
||||
|
||||
@ -109,5 +109,4 @@ class EventManager
|
||||
{
|
||||
$this->addEventListener($subscriber->getSubscribedEvents(), $subscriber);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -154,9 +154,11 @@ class Connection
|
||||
* Initializes a new instance of the Connection class.
|
||||
*
|
||||
* @param array $params The connection parameters.
|
||||
* @param Driver $driver
|
||||
* @param Configuration $config
|
||||
* @param EventManager $eventManager
|
||||
*/
|
||||
public function __construct(array $params, Driver $driver,
|
||||
Configuration $config = null,
|
||||
public function __construct(array $params, Driver $driver, Configuration $config = null,
|
||||
EventManager $eventManager = null)
|
||||
{
|
||||
$this->_driver = $driver;
|
||||
@ -182,7 +184,7 @@ class Connection
|
||||
/**
|
||||
* Gets the Configuration used by the Connection.
|
||||
*
|
||||
* @return Configuration
|
||||
* @return Doctrine\DBAL\Configuration
|
||||
*/
|
||||
public function getConfiguration()
|
||||
{
|
||||
@ -389,23 +391,23 @@ class Connection
|
||||
}
|
||||
|
||||
/**
|
||||
* fetchAll
|
||||
* Convenience method for PDO::query("...") followed by $stmt->fetchAll(PDO::FETCH_ASSOC).
|
||||
*
|
||||
* @param string $statement sql query to be executed
|
||||
* @param array $params prepared statement params
|
||||
* @param string $sql The SQL query.
|
||||
* @param array $params The query parameters.
|
||||
* @return array
|
||||
*/
|
||||
public function fetchAll($statement, array $params = array())
|
||||
public function fetchAll($sql, array $params = array())
|
||||
{
|
||||
return $this->execute($statement, $params)->fetchAll(PDO::FETCH_ASSOC);
|
||||
return $this->execute($sql, $params)->fetchAll(PDO::FETCH_ASSOC);
|
||||
}
|
||||
|
||||
/**
|
||||
* fetchOne
|
||||
* Convenience method for PDO::query("...") followed by $stmt->fetchColumn().
|
||||
*
|
||||
* @param string $statement sql query to be executed
|
||||
* @param array $params prepared statement params
|
||||
* @param int $colnum 0-indexed column number to retrieve
|
||||
* @param string $statement The SQL query.
|
||||
* @param array $params The query parameters.
|
||||
* @param int $colnum 0-indexed column number to retrieve
|
||||
* @return mixed
|
||||
*/
|
||||
public function fetchOne($statement, array $params = array(), $colnum = 0)
|
||||
@ -414,10 +416,10 @@ class Connection
|
||||
}
|
||||
|
||||
/**
|
||||
* fetchRow
|
||||
* Convenience method for PDO::query("...") followed by $stmt->fetch(PDO::FETCH_ASSOC).
|
||||
*
|
||||
* @param string $statement sql query to be executed
|
||||
* @param array $params prepared statement params
|
||||
* @param string $statement The SQL query.
|
||||
* @param array $params The query parameters.
|
||||
* @return array
|
||||
*/
|
||||
public function fetchRow($statement, array $params = array())
|
||||
@ -426,7 +428,7 @@ class Connection
|
||||
}
|
||||
|
||||
/**
|
||||
* fetchArray
|
||||
* Convenience method for PDO::query("...") followed by $stmt->fetch(PDO::FETCH_NUM).
|
||||
*
|
||||
* @param string $statement sql query to be executed
|
||||
* @param array $params prepared statement params
|
||||
@ -438,7 +440,7 @@ class Connection
|
||||
}
|
||||
|
||||
/**
|
||||
* fetchColumn
|
||||
* Convenience method for PDO::query("...") followed by $stmt->fetchAll(PDO::FETCH_COLUMN, ...).
|
||||
*
|
||||
* @param string $statement sql query to be executed
|
||||
* @param array $params prepared statement params
|
||||
@ -451,19 +453,7 @@ class Connection
|
||||
}
|
||||
|
||||
/**
|
||||
* fetchAssoc
|
||||
*
|
||||
* @param string $statement sql query to be executed
|
||||
* @param array $params prepared statement params
|
||||
* @return array
|
||||
*/
|
||||
public function fetchAssoc($statement, array $params = array())
|
||||
{
|
||||
return $this->execute($statement, $params)->fetchAll(PDO::FETCH_ASSOC);
|
||||
}
|
||||
|
||||
/**
|
||||
* fetchBoth
|
||||
* Convenience method for PDO::query("...") followed by $stmt->fetchAll(PDO::FETCH_BOTH).
|
||||
*
|
||||
* @param string $statement sql query to be executed
|
||||
* @param array $params prepared statement params
|
||||
@ -478,7 +468,7 @@ class Connection
|
||||
* Prepares an SQL statement.
|
||||
*
|
||||
* @param string $statement
|
||||
* @return Doctrine::DBAL::Statement
|
||||
* @return PDOStatement
|
||||
*/
|
||||
public function prepare($statement)
|
||||
{
|
||||
@ -487,13 +477,13 @@ class Connection
|
||||
}
|
||||
|
||||
/**
|
||||
* Queries the database with limit and offset
|
||||
* added to the query and returns a Doctrine_Connection_Statement object
|
||||
* Queries the database with limit and offset added to the query and returns
|
||||
* a Statement object.
|
||||
*
|
||||
* @param string $query
|
||||
* @param integer $limit
|
||||
* @param integer $offset
|
||||
* @return Doctrine_Connection_Statement
|
||||
* @return Statement
|
||||
*/
|
||||
public function select($query, $limit = 0, $offset = 0)
|
||||
{
|
||||
|
@ -17,23 +17,21 @@
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information, see
|
||||
* <http://www.phpdoctrine.org>.
|
||||
* <http://www.doctrine-project.org>.
|
||||
*/
|
||||
|
||||
namespace Doctrine\ORM;
|
||||
|
||||
/**
|
||||
* Doctrine_ORM_Query_Abstract
|
||||
* Base class for Query and NativeQuery.
|
||||
*
|
||||
* @package Doctrine
|
||||
* @subpackage Query
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.phpdoctrine.com
|
||||
* @link www.doctrine-project.com
|
||||
* @since 1.0
|
||||
* @version $Revision: 1393 $
|
||||
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
|
||||
* @author Konsta Vesterinen <kvesteri@cc.hut.fi>
|
||||
* @todo See {@link Doctrine_ORM_Query}
|
||||
* @author Roman Borschel <roman@code-factory.org>
|
||||
*/
|
||||
abstract class AbstractQuery
|
||||
{
|
||||
@ -101,7 +99,7 @@ abstract class AbstractQuery
|
||||
/**
|
||||
* @var integer $type Query type.
|
||||
*
|
||||
* @see Doctrine_ORM_Query::* constants
|
||||
* @see Query::* constants
|
||||
*/
|
||||
protected $_type = self::SELECT;
|
||||
|
||||
@ -112,19 +110,19 @@ abstract class AbstractQuery
|
||||
|
||||
/**
|
||||
* @var array $params Parameters of this query.
|
||||
* @see Doctrine_ORM_Query::free that initializes this property
|
||||
* @see Query::free that initializes this property
|
||||
*/
|
||||
protected $_params = array();
|
||||
|
||||
/**
|
||||
* @var array $_enumParams Array containing the keys of the parameters that should be enumerated.
|
||||
* @see Doctrine_ORM_Query::free that initializes this property
|
||||
* @see Query::free that initializes this property
|
||||
*/
|
||||
protected $_enumParams = array();
|
||||
|
||||
/**
|
||||
* @var array $_dqlParts An array containing all DQL query parts.
|
||||
* @see Doctrine_ORM_Query::free that initializes this property
|
||||
* @see Query::free that initializes this property
|
||||
*/
|
||||
protected $_dqlParts = array();
|
||||
|
||||
|
@ -24,7 +24,6 @@ namespace Doctrine\ORM;
|
||||
use Doctrine\Common\EventManager;
|
||||
use Doctrine\Common\DoctrineException;
|
||||
use Doctrine\DBAL\Connection;
|
||||
use Doctrine\ORM\Exceptions\EntityManagerException;
|
||||
use Doctrine\ORM\Mapping\ClassMetadata;
|
||||
use Doctrine\ORM\Mapping\ClassMetadataFactory;
|
||||
|
||||
@ -90,7 +89,7 @@ class EntityManager
|
||||
private $_conn;
|
||||
|
||||
/**
|
||||
* The metadata factory, used to retrieve the metadata of entity classes.
|
||||
* The metadata factory, used to retrieve the ORM metadata of entity classes.
|
||||
*
|
||||
* @var Doctrine\ORM\Mapping\ClassMetadataFactory
|
||||
*/
|
||||
@ -330,7 +329,7 @@ class EntityManager
|
||||
*/
|
||||
public function flush()
|
||||
{
|
||||
$this->_errorIfNotActiveOrClosed();
|
||||
$this->_errorIfClosed();
|
||||
$this->_unitOfWork->commit();
|
||||
}
|
||||
|
||||
@ -412,7 +411,7 @@ class EntityManager
|
||||
*/
|
||||
public function save($object)
|
||||
{
|
||||
$this->_errorIfNotActiveOrClosed();
|
||||
$this->_errorIfClosed();
|
||||
$this->_unitOfWork->save($object);
|
||||
if ($this->_flushMode == self::FLUSHMODE_IMMEDIATE) {
|
||||
$this->flush();
|
||||
@ -426,7 +425,7 @@ class EntityManager
|
||||
*/
|
||||
public function delete($entity)
|
||||
{
|
||||
$this->_errorIfNotActiveOrClosed();
|
||||
$this->_errorIfClosed();
|
||||
$this->_unitOfWork->delete($entity);
|
||||
if ($this->_flushMode == self::FLUSHMODE_IMMEDIATE) {
|
||||
$this->flush();
|
||||
@ -459,7 +458,7 @@ class EntityManager
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the repository for an Entity.
|
||||
* Gets the repository for an entity class.
|
||||
*
|
||||
* @param string $entityName The name of the Entity.
|
||||
* @return Doctrine\ORM\EntityRepository The repository.
|
||||
@ -520,7 +519,7 @@ class EntityManager
|
||||
*
|
||||
* @throws EntityManagerException If the EntityManager is closed or not active.
|
||||
*/
|
||||
private function _errorIfNotActiveOrClosed()
|
||||
private function _errorIfClosed()
|
||||
{
|
||||
if ($this->_closed) {
|
||||
throw EntityManagerException::notActiveOrClosed($this->_name);
|
||||
|
@ -16,10 +16,10 @@
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information, see
|
||||
* <http://www.phpdoctrine.org>.
|
||||
* <http://www.doctrine-project.org>.
|
||||
*/
|
||||
|
||||
namespace Doctrine\ORM\Exceptions;
|
||||
namespace Doctrine\ORM;
|
||||
|
||||
/**
|
||||
* Doctrine_EntityManager_Exception
|
||||
@ -27,7 +27,7 @@ namespace Doctrine\ORM\Exceptions;
|
||||
* @author Konsta Vesterinen <kvesteri@cc.hut.fi>
|
||||
* @author Roman Borschel <roman@code-factory.org>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.phpdoctrine.org
|
||||
* @link www.doctrine-project.org
|
||||
* @since 2.0
|
||||
* @version $Revision$
|
||||
*/
|
@ -1,37 +1,42 @@
|
||||
<?php
|
||||
/*
|
||||
* $Id: Exception.php 4776 2008-08-16 19:40:59Z romanb $
|
||||
*
|
||||
* 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.org>.
|
||||
*/
|
||||
<?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.doctrine-project.org>.
|
||||
*/
|
||||
|
||||
namespace Doctrine\ORM;
|
||||
|
||||
/**
|
||||
* Container for all ORM events.
|
||||
*
|
||||
* This class cannot be instantiated.
|
||||
*
|
||||
* @author robo
|
||||
* @since 2.0
|
||||
*/
|
||||
final class Events
|
||||
{
|
||||
private function __construct() {}
|
||||
|
||||
const preDelete = 'preDelete';
|
||||
const postDelete = 'postDelete';
|
||||
const preSave = 'preSave';
|
||||
const postSave = 'postSave';
|
||||
|
||||
}
|
||||
|
||||
#namespace Doctrine::ORM::Exceptions;
|
||||
|
||||
/**
|
||||
* Doctrine_Exception
|
||||
*
|
||||
* @package Doctrine
|
||||
* @subpackage Exception
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.phpdoctrine.org
|
||||
* @since 1.0
|
||||
* @version $Revision: 4776 $
|
||||
* @author Konsta Vesterinen <kvesteri@cc.hut.fi>
|
||||
* @author Roman Borschel <roman@code-factory.org>
|
||||
*/
|
||||
class Doctrine_ORM_Exceptions_ORMException extends Doctrine_Common_Exceptions_DoctrineException
|
||||
{}
|
@ -1,65 +0,0 @@
|
||||
<?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.org>.
|
||||
*/
|
||||
|
||||
#namespace Doctrine::ORM::Exceptions;
|
||||
|
||||
/**
|
||||
* Doctrine_Entity_Exception
|
||||
*
|
||||
* @package Doctrine
|
||||
* @subpackage Entity
|
||||
* @author Konsta Vesterinen <kvesteri@cc.hut.fi>
|
||||
* @author Roman Borschel <roman@code-factory.org>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.phpdoctrine.org
|
||||
* @since 2.0
|
||||
* @version $Revision$
|
||||
*/
|
||||
class Doctrine_ORM_Exceptions_EntityException extends Doctrine_ORM_Exceptions_ORMException
|
||||
{
|
||||
public static function unknownField($field)
|
||||
{
|
||||
return new self("Undefined field: '$field'.");
|
||||
}
|
||||
|
||||
public static function invalidValueForOneToManyReference()
|
||||
{
|
||||
return new self("Invalid value. The value of a reference in a OneToMany "
|
||||
. "association must be a Collection.");
|
||||
}
|
||||
|
||||
public static function invalidValueForOneToOneReference()
|
||||
{
|
||||
return new self("Invalid value. The value of a reference in a OneToOne "
|
||||
. "association must be an Entity.");
|
||||
}
|
||||
|
||||
public static function invalidValueForManyToManyReference()
|
||||
{
|
||||
return new self("Invalid value. The value of a reference in a ManyToMany "
|
||||
. "association must be a Collection.");
|
||||
}
|
||||
|
||||
public static function invalidField($field)
|
||||
{
|
||||
return new self("Invalid field: '$field'.");
|
||||
}
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\ORM\Exceptions;
|
||||
namespace Doctrine\ORM\Internal\Hydration;
|
||||
|
||||
class HydrationException extends \Doctrine\Common\DoctrineException
|
||||
{
|
@ -1,13 +1,33 @@
|
||||
<?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.doctrine-project.org>.
|
||||
*/
|
||||
|
||||
namespace Doctrine\ORM\Internal\Hydration;
|
||||
|
||||
use \PDO;
|
||||
|
||||
/**
|
||||
* Description of ObjectHydrator
|
||||
* The ObjectHydrator constructs an object graph out of an SQL result set.
|
||||
*
|
||||
* @author robo
|
||||
* @since 2.0
|
||||
*/
|
||||
class ObjectHydrator extends AbstractHydrator
|
||||
{
|
||||
@ -64,8 +84,8 @@ class ObjectHydrator extends AbstractHydrator
|
||||
|
||||
// Take snapshots from all initialized collections
|
||||
foreach ($this->_collections as $coll) {
|
||||
$coll->_takeSnapshot();
|
||||
$coll->_setHydrationFlag(false);
|
||||
$coll->takeSnapshot();
|
||||
$coll->setHydrationFlag(false);
|
||||
}
|
||||
|
||||
// Clean up
|
||||
@ -128,8 +148,8 @@ class ObjectHydrator extends AbstractHydrator
|
||||
$relation = $classMetadata->getAssociationMapping($name);
|
||||
$relatedClass = $this->_em->getClassMetadata($relation->getTargetEntityName());
|
||||
$coll = $this->getCollection($relatedClass->getClassName());
|
||||
$coll->_setOwner($entity, $relation);
|
||||
$coll->_setHydrationFlag(true);
|
||||
$coll->setOwner($entity, $relation);
|
||||
$coll->setHydrationFlag(true);
|
||||
$classMetadata->getReflectionProperty($name)->setValue($entity, $coll);
|
||||
$this->_initializedRelations[$oid][$name] = true;
|
||||
$this->_uow->setOriginalEntityProperty($oid, $name, $coll);
|
||||
|
@ -7,7 +7,6 @@
|
||||
namespace Doctrine\ORM\Internal\Hydration;
|
||||
|
||||
use \PDO;
|
||||
use Doctrine\ORM\Exceptions\HydrationException;
|
||||
|
||||
/**
|
||||
* Description of SingleScalarHydrator
|
||||
|
@ -21,8 +21,6 @@
|
||||
|
||||
namespace Doctrine\ORM\Mapping;
|
||||
|
||||
use Doctrine\ORM\Exceptions\MappingException;
|
||||
|
||||
/**
|
||||
* Base class for association mappings.
|
||||
*
|
||||
|
@ -16,19 +16,17 @@
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information, see
|
||||
* <http://www.phpdoctrine.org>.
|
||||
* <http://www.doctrine-project.org>.
|
||||
*/
|
||||
|
||||
namespace Doctrine\ORM\Mapping;
|
||||
|
||||
use \ReflectionClass;
|
||||
use Doctrine\Common\DoctrineException;
|
||||
use Doctrine\ORM\Exceptions\MappingException;
|
||||
|
||||
/**
|
||||
* A <tt>ClassMetadata</tt> instance holds all the information (metadata) of an entity and
|
||||
* it's associations and how they're mapped to a relational database.
|
||||
* It is the backbone of Doctrine's metadata mapping.
|
||||
* A <tt>ClassMetadata</tt> instance holds all the ORM metadata of an entity and
|
||||
* it's associations. It is the backbone of Doctrine's metadata mapping.
|
||||
*
|
||||
* @author Roman Borschel <roman@code-factory.org>
|
||||
* @since 2.0
|
||||
@ -176,8 +174,8 @@ class ClassMetadata
|
||||
* - <b>fieldName</b> (string)
|
||||
* The name of the field in the Entity.
|
||||
*
|
||||
* - <b>type</b> (object Doctrine::DBAL::Types::* or custom type)
|
||||
* The database type of the column. Can be one of Doctrine's portable types
|
||||
* - <b>type</b> (object Doctrine\DBAL\Types\* or custom type)
|
||||
* The type of the column. Can be one of Doctrine's portable types
|
||||
* or a custom type.
|
||||
*
|
||||
* - <b>columnName</b> (string, optional)
|
||||
@ -198,7 +196,7 @@ class ClassMetadata
|
||||
* therefore cant be used as a generator name!
|
||||
*
|
||||
* - <b>nullable</b> (boolean, optional)
|
||||
* Whether the column is nullable. Defaults to TRUE.
|
||||
* Whether the column is nullable. Defaults to FALSE.
|
||||
*
|
||||
* - <b>columnDefinition</b> (string, optional, schema-only)
|
||||
* The SQL fragment that is used when generating the DDL for the column.
|
||||
@ -226,7 +224,7 @@ class ClassMetadata
|
||||
protected $_fieldMappings = array();
|
||||
|
||||
/**
|
||||
* An array of field names. used to look up field names from column names.
|
||||
* An array of field names. Used to look up field names from column names.
|
||||
* Keys are column names and values are field names.
|
||||
* This is the reverse lookup map of $_columnNames.
|
||||
*
|
||||
@ -244,7 +242,7 @@ class ClassMetadata
|
||||
protected $_columnNames = array();
|
||||
|
||||
/**
|
||||
* Map that maps lowercased column names to field names.
|
||||
* Map that maps lowercased column names (keys) to field names (values).
|
||||
* Mainly used during hydration because Doctrine enforces PDO_CASE_LOWER
|
||||
* for portability.
|
||||
*
|
||||
@ -254,7 +252,8 @@ class ClassMetadata
|
||||
|
||||
/**
|
||||
* Whether to automatically OUTER JOIN subtypes when a basetype is queried.
|
||||
* This does only apply to the JOINED inheritance mapping strategy.
|
||||
*
|
||||
* <b>This does only apply to the JOINED inheritance mapping strategy.</b>
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
@ -262,8 +261,9 @@ class ClassMetadata
|
||||
|
||||
/**
|
||||
* A map that maps discriminator values to class names.
|
||||
* This does only apply to the JOINED and SINGLE_TABLE inheritance mapping strategies
|
||||
* where a discriminator column is used.
|
||||
*
|
||||
* <b>This does only apply to the JOINED and SINGLE_TABLE inheritance mapping strategies
|
||||
* where a discriminator column is used.</b>
|
||||
*
|
||||
* @var array
|
||||
* @see _discriminatorColumn
|
||||
@ -299,14 +299,14 @@ class ClassMetadata
|
||||
protected $_lifecycleListenerInstances = array();
|
||||
|
||||
/**
|
||||
* The registered lifecycle callbacks for Entities of this class.
|
||||
* The registered lifecycle callbacks for entities of this class.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $_lifecycleCallbacks = array();
|
||||
|
||||
/**
|
||||
* The registered lifecycle listeners for Entities of this class.
|
||||
* The registered lifecycle listeners for entities of this class.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
@ -394,8 +394,10 @@ class ClassMetadata
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the ReflectionProperty for the single identifier field.
|
||||
*
|
||||
* @return <type>
|
||||
* @return ReflectionProperty
|
||||
* @throws DoctrineException If the class has a composite identifier.
|
||||
*/
|
||||
public function getSingleIdReflectionProperty()
|
||||
{
|
||||
@ -478,7 +480,7 @@ class ClassMetadata
|
||||
{
|
||||
$mapping = $this->getFieldMapping($fieldName);
|
||||
if ($mapping !== false) {
|
||||
return isset($mapping['notnull']) && $mapping['notnull'] == true;
|
||||
return isset($mapping['nullable']) && $mapping['nullable'] == false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@ -502,7 +504,7 @@ class ClassMetadata
|
||||
* reference to another object.
|
||||
*
|
||||
* @param string $fieldName The field name.
|
||||
* @return array The mapping.
|
||||
* @return array The field mapping.
|
||||
*/
|
||||
public function getFieldMapping($fieldName)
|
||||
{
|
||||
@ -522,7 +524,7 @@ class ClassMetadata
|
||||
public function getAssociationMapping($fieldName)
|
||||
{
|
||||
if ( ! isset($this->_associationMappings[$fieldName])) {
|
||||
throw new Doctrine_Exception("Mapping not found: $fieldName");
|
||||
throw MappingException::mappingNotFound($fieldName);
|
||||
}
|
||||
return $this->_associationMappings[$fieldName];
|
||||
}
|
||||
@ -536,7 +538,7 @@ class ClassMetadata
|
||||
public function getInverseAssociationMapping($mappedByFieldName)
|
||||
{
|
||||
if ( ! isset($this->_inverseMappings[$mappedByFieldName])) {
|
||||
throw new DoctrineException("Mapping not found: " . $mappedByFieldName);
|
||||
throw MappingException::mappingNotFound($mappedByFieldName);
|
||||
}
|
||||
return $this->_inverseMappings[$mappedByFieldName];
|
||||
}
|
||||
@ -564,6 +566,7 @@ class ClassMetadata
|
||||
|
||||
/**
|
||||
* Gets all association mappings of the class.
|
||||
*
|
||||
* Alias for getAssociationMappings().
|
||||
*
|
||||
* @return array
|
||||
@ -590,9 +593,8 @@ class ClassMetadata
|
||||
* Gets the field name for a completely lowercased column name.
|
||||
* Mainly used during hydration.
|
||||
*
|
||||
* @param string $lcColumnName
|
||||
* @return string
|
||||
* @todo Better name.
|
||||
* @param string $lcColumnName The all-lowercase column name.
|
||||
* @return string The field name.
|
||||
*/
|
||||
public function getFieldNameForLowerColumnName($lcColumnName)
|
||||
{
|
||||
@ -612,7 +614,7 @@ class ClassMetadata
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates & completes the field mapping.
|
||||
* Validates & completes the given field mapping.
|
||||
*
|
||||
* @param array $mapping The field mapping to validated & complete.
|
||||
* @return array The validated and completed field mapping.
|
||||
@ -668,11 +670,6 @@ class ClassMetadata
|
||||
$refProp->setAccessible(true);
|
||||
$this->_reflectionProperties[$mapping['fieldName']] = $refProp;
|
||||
}
|
||||
|
||||
private function _validateAndCompleteClassMapping(array &$mapping)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @todo Implementation of Optimistic Locking.
|
||||
@ -760,7 +757,6 @@ class ClassMetadata
|
||||
* Gets all field mappings.
|
||||
*
|
||||
* @return array
|
||||
* @deprecated
|
||||
*/
|
||||
public function getFieldMappings()
|
||||
{
|
||||
@ -792,7 +788,7 @@ class ClassMetadata
|
||||
*/
|
||||
public function getIdentifierColumnNames()
|
||||
{
|
||||
return $this->getColumnNames((array) $this->getIdentifier());
|
||||
return $this->getColumnNames((array)$this->getIdentifierFieldNames());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -920,18 +916,18 @@ class ClassMetadata
|
||||
* Gets the type of a field.
|
||||
*
|
||||
* @param string $fieldName
|
||||
* @return string
|
||||
* @return Doctrine\DBAL\Types\Type
|
||||
*/
|
||||
public function getTypeOfField($fieldName)
|
||||
{
|
||||
return isset($this->_fieldMappings[$fieldName]) ?
|
||||
$this->_fieldMappings[$fieldName]['type'] : false;
|
||||
$this->_fieldMappings[$fieldName]['type'] : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* getTypeOfColumn
|
||||
* Gets the type of a column.
|
||||
*
|
||||
* @return mixed The column type or FALSE if the type cant be determined.
|
||||
* @return Doctrine\DBAL\Types\Type
|
||||
*/
|
||||
public function getTypeOfColumn($columnName)
|
||||
{
|
||||
@ -985,8 +981,9 @@ class ClassMetadata
|
||||
|
||||
/**
|
||||
* Sets the subclasses of the mapped class.
|
||||
* All entity classes that participate in a hierarchy and have subclasses
|
||||
* need to declare them this way.
|
||||
*
|
||||
* <b>All entity classes that participate in a hierarchy and have subclasses
|
||||
* need to declare them this way.</b>
|
||||
*
|
||||
* @param array $subclasses The names of all subclasses.
|
||||
*/
|
||||
@ -1055,11 +1052,6 @@ class ClassMetadata
|
||||
*/
|
||||
public function setInheritanceType($type)
|
||||
{
|
||||
if ($parentClassNames = $this->getParentClasses()) {
|
||||
throw new MappingException("All classes in an inheritance hierarchy"
|
||||
. " must share the same inheritance mapping type and this type must be set"
|
||||
. " in the root class of the hierarchy.");
|
||||
}
|
||||
if ( ! $this->_isInheritanceType($type)) {
|
||||
throw MappingException::invalidInheritanceType($type);
|
||||
}
|
||||
@ -1067,31 +1059,7 @@ class ClassMetadata
|
||||
}
|
||||
|
||||
/**
|
||||
* exports this class to the database based on its mapping.
|
||||
*
|
||||
* @throws Doctrine_Connection_Exception If some error other than Doctrine::ERR_ALREADY_EXISTS
|
||||
* occurred during the create table operation.
|
||||
* @return boolean Whether or not the export operation was successful
|
||||
* false if table already existed in the database.
|
||||
* @todo Reimpl. & Placement.
|
||||
*/
|
||||
public function export()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array with all the information needed to create the main database table
|
||||
* for the class.
|
||||
*
|
||||
* @return array
|
||||
* @todo Reimpl. & placement.
|
||||
*/
|
||||
public function getExportableFormat($parseForeignKeys = true)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether a persistent field is inherited from a superclass.
|
||||
* Checks whether a mapped field is inherited from a superclass.
|
||||
*
|
||||
* @return boolean TRUE if the field is inherited, FALSE otherwise.
|
||||
*/
|
||||
@ -1104,6 +1072,7 @@ class ClassMetadata
|
||||
* Sets the name of the primary table the class is mapped to.
|
||||
*
|
||||
* @param string $tableName The table name.
|
||||
* @deprecated
|
||||
*/
|
||||
public function setTableName($tableName)
|
||||
{
|
||||
@ -1208,6 +1177,13 @@ class ClassMetadata
|
||||
$this->_fieldMappings[$mapping['fieldName']] = $mapping;
|
||||
}
|
||||
|
||||
/**
|
||||
* INTERNAL:
|
||||
* Adds an association mapping without completing/validating it.
|
||||
* This is mainly used to add inherited association mappings to derived classes.
|
||||
*
|
||||
* @param AssociationMapping $mapping
|
||||
*/
|
||||
public function addAssociationMapping(AssociationMapping $mapping)
|
||||
{
|
||||
$this->_storeAssociationMapping($mapping);
|
||||
@ -1320,7 +1296,7 @@ class ClassMetadata
|
||||
* class is queried in a class hierarchy that uses the JOINED inheritance mapping
|
||||
* strategy.
|
||||
*
|
||||
* This options does only apply to the JOINED inheritance mapping strategy.
|
||||
* <b>This options does only apply to the JOINED inheritance mapping strategy.</b>
|
||||
*
|
||||
* @param boolean $bool
|
||||
* @see getJoinSubClasses()
|
||||
@ -1415,7 +1391,7 @@ class ClassMetadata
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a lifecycle callback for Entities of this class.
|
||||
* Adds a lifecycle callback for entities of this class.
|
||||
*
|
||||
* Note: If the same callback is registered more than once, the old one
|
||||
* will be overridden.
|
||||
@ -1444,16 +1420,6 @@ class ClassMetadata
|
||||
$this->_discriminatorColumn = $columnDef;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param <type> $fieldName
|
||||
* @param <type> $mapping
|
||||
*/
|
||||
/*public function addFieldMapping($fieldName, array $mapping)
|
||||
{
|
||||
$this->_fieldMappings[$fieldName] = $mapping;
|
||||
}*/
|
||||
|
||||
/**
|
||||
* Gets the discriminator column definition.
|
||||
*
|
||||
|
@ -22,7 +22,7 @@
|
||||
namespace Doctrine\ORM\Mapping\Driver;
|
||||
|
||||
use Doctrine\ORM\Mapping\ClassMetadata;
|
||||
use Doctrine\ORM\Exceptions\MappingException;
|
||||
use Doctrine\ORM\Mapping\MappingException;
|
||||
|
||||
/* Addendum annotation reflection extensions */
|
||||
if ( ! class_exists('\Addendum', false)) {
|
||||
@ -134,6 +134,7 @@ class AnnotationDriver
|
||||
$metadata->mapOneToMany($mapping);
|
||||
} else if ($manyToOneAnnot = $property->getAnnotation('DoctrineManyToOne')) {
|
||||
$mapping['joinColumns'] = $joinColumns;
|
||||
$mapping['cascade'] = $manyToOneAnnot->cascade;
|
||||
$mapping['targetEntity'] = $manyToOneAnnot->targetEntity;
|
||||
$metadata->mapManyToOne($mapping);
|
||||
} else if ($manyToManyAnnot = $property->getAnnotation('DoctrineManyToMany')) {
|
||||
@ -150,6 +151,7 @@ class AnnotationDriver
|
||||
$mapping['joinTable'] = $joinTable;
|
||||
$mapping['targetEntity'] = $manyToManyAnnot->targetEntity;
|
||||
$mapping['mappedBy'] = $manyToManyAnnot->mappedBy;
|
||||
$mapping['cascade'] = $manyToManyAnnot->cascade;
|
||||
$metadata->mapManyToMany($mapping);
|
||||
}
|
||||
|
||||
|
@ -21,8 +21,6 @@
|
||||
|
||||
namespace Doctrine\ORM\Mapping;
|
||||
|
||||
use Doctrine\ORM\Exceptions\MappingException;
|
||||
|
||||
/**
|
||||
* A many-to-many mapping describes the mapping between two collections of
|
||||
* entities.
|
||||
|
@ -19,7 +19,7 @@
|
||||
* <http://www.phpdoctrine.org>.
|
||||
*/
|
||||
|
||||
namespace Doctrine\ORM\Exceptions;
|
||||
namespace Doctrine\ORM\Mapping;
|
||||
|
||||
/**
|
||||
* A MappingException indicates that something is wrong with the mapping setup.
|
@ -21,8 +21,6 @@
|
||||
|
||||
namespace Doctrine\ORM\Mapping;
|
||||
|
||||
use Doctrine\ORM\Exceptions\MappingException;
|
||||
|
||||
/**
|
||||
* Represents a one-to-many mapping.
|
||||
*
|
||||
@ -53,7 +51,7 @@ class OneToManyMapping extends AssociationMapping
|
||||
//protected $_sourceKeysToTargetForeignKeys;
|
||||
|
||||
/** Whether to delete orphaned elements (removed from the collection) */
|
||||
protected $_deleteOrphans = false;
|
||||
private $_deleteOrphans = false;
|
||||
|
||||
/**
|
||||
* Initializes a new OneToManyMapping.
|
||||
@ -96,9 +94,8 @@ class OneToManyMapping extends AssociationMapping
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the association is one-to-many.
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return boolean TRUE if the association is one-to-many, FALSE otherwise.
|
||||
* @override
|
||||
*/
|
||||
public function isOneToMany()
|
||||
|
@ -21,8 +21,6 @@
|
||||
|
||||
namespace Doctrine\ORM\Mapping;
|
||||
|
||||
use Doctrine\ORM\Exceptions\MappingException;
|
||||
|
||||
/**
|
||||
* A one-to-one mapping describes a uni-directional mapping from one entity
|
||||
* to another entity.
|
||||
|
@ -48,7 +48,7 @@ final class PersistentCollection extends \Doctrine\Common\Collections\Collection
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $_entityBaseType;
|
||||
private $_type;
|
||||
|
||||
/**
|
||||
* A snapshot of the collection at the moment it was fetched from the database.
|
||||
@ -99,7 +99,7 @@ final class PersistentCollection extends \Doctrine\Common\Collections\Collection
|
||||
* Hydration flag.
|
||||
*
|
||||
* @var boolean
|
||||
* @see _setHydrationFlag()
|
||||
* @see setHydrationFlag()
|
||||
*/
|
||||
private $_hydrationFlag;
|
||||
|
||||
@ -119,12 +119,12 @@ final class PersistentCollection extends \Doctrine\Common\Collections\Collection
|
||||
/**
|
||||
* Creates a new persistent collection.
|
||||
*/
|
||||
public function __construct(EntityManager $em, $entityBaseType, array $data = array(), $keyField = null)
|
||||
public function __construct(EntityManager $em, $type, array $data = array(), $keyField = null)
|
||||
{
|
||||
parent::__construct($data);
|
||||
$this->_entityBaseType = $entityBaseType;
|
||||
$this->_type = $type;
|
||||
$this->_em = $em;
|
||||
$this->_ownerClass = $em->getClassMetadata($entityBaseType);
|
||||
$this->_ownerClass = $em->getClassMetadata($type);
|
||||
if ($keyField !== null) {
|
||||
if ( ! $this->_ownerClass->hasField($keyField)) {
|
||||
throw new DoctrineException("Invalid field '$keyField' can't be used as key.");
|
||||
@ -162,7 +162,7 @@ final class PersistentCollection extends \Doctrine\Common\Collections\Collection
|
||||
* @param object $entity
|
||||
* @param AssociationMapping $assoc
|
||||
*/
|
||||
public function _setOwner($entity, AssociationMapping $assoc)
|
||||
public function setOwner($entity, AssociationMapping $assoc)
|
||||
{
|
||||
$this->_owner = $entity;
|
||||
$this->_association = $assoc;
|
||||
@ -289,7 +289,7 @@ final class PersistentCollection extends \Doctrine\Common\Collections\Collection
|
||||
*
|
||||
* @param boolean $bool
|
||||
*/
|
||||
public function _setHydrationFlag($bool)
|
||||
public function setHydrationFlag($bool)
|
||||
{
|
||||
$this->_hydrationFlag = $bool;
|
||||
}
|
||||
@ -301,9 +301,9 @@ final class PersistentCollection extends \Doctrine\Common\Collections\Collection
|
||||
* when a fetched collection has three elements, then two of those
|
||||
* are being removed the diff would contain one element.
|
||||
*/
|
||||
public function _takeSnapshot()
|
||||
public function takeSnapshot()
|
||||
{
|
||||
$this->_snapshot = $this->_data;
|
||||
$this->_snapshot = $this->_elements;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -312,7 +312,7 @@ final class PersistentCollection extends \Doctrine\Common\Collections\Collection
|
||||
*
|
||||
* @return array The last snapshot of the elements.
|
||||
*/
|
||||
public function _getSnapshot()
|
||||
public function getSnapshot()
|
||||
{
|
||||
return $this->_snapshot;
|
||||
}
|
||||
@ -325,7 +325,7 @@ final class PersistentCollection extends \Doctrine\Common\Collections\Collection
|
||||
*/
|
||||
public function getDeleteDiff()
|
||||
{
|
||||
return array_udiff($this->_snapshot, $this->_data, array($this, '_compareRecords'));
|
||||
return array_udiff($this->_snapshot, $this->_elements, array($this, '_compareRecords'));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -335,7 +335,7 @@ final class PersistentCollection extends \Doctrine\Common\Collections\Collection
|
||||
*/
|
||||
public function getInsertDiff()
|
||||
{
|
||||
return array_udiff($this->_data, $this->_snapshot, array($this, '_compareRecords'));
|
||||
return array_udiff($this->_elements, $this->_snapshot, array($this, '_compareRecords'));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -66,20 +66,36 @@ abstract class AbstractCollectionPersister
|
||||
if ($coll->getMapping()->isInverseSide()) {
|
||||
return; // ignore inverse side
|
||||
}
|
||||
|
||||
$sql = $this->_getDeleteSql($coll);
|
||||
$this->_conn->exec($sql, $this->_getDeleteSqlParameters($coll));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the SQL statement for deleting the given collection.
|
||||
*
|
||||
* @param PersistentCollection $coll
|
||||
*/
|
||||
abstract protected function _getDeleteSql(PersistentCollection $coll);
|
||||
|
||||
/**
|
||||
* Gets the SQL parameters for the corresponding SQL statement to delete
|
||||
* the given collection.
|
||||
*
|
||||
* @param PersistentCollection $coll
|
||||
*/
|
||||
abstract protected function _getDeleteSqlParameters(PersistentCollection $coll);
|
||||
|
||||
/**
|
||||
* Updates the given collection, synchronizing it's state with the database
|
||||
* by inserting, updating and deleting individual elements.
|
||||
*
|
||||
* @param PersistentCollection $coll
|
||||
*/
|
||||
public function update(PersistentCollection $coll)
|
||||
{
|
||||
if ($coll->getMapping()->isInverseSide()) {
|
||||
return; // ignore inverse side
|
||||
}
|
||||
|
||||
$this->deleteRows($coll);
|
||||
//$this->updateRows($coll);
|
||||
$this->insertRows($coll);
|
||||
@ -113,6 +129,13 @@ abstract class AbstractCollectionPersister
|
||||
*/
|
||||
abstract protected function _getDeleteRowSql(PersistentCollection $coll);
|
||||
|
||||
/**
|
||||
* Gets the SQL parameters for the corresponding SQL statement to delete the given
|
||||
* element from the given collection.
|
||||
*
|
||||
* @param PersistentCollection $coll
|
||||
* @param mixed $element
|
||||
*/
|
||||
abstract protected function _getDeleteRowSqlParameters(PersistentCollection $coll, $element);
|
||||
|
||||
/**
|
||||
@ -128,7 +151,14 @@ abstract class AbstractCollectionPersister
|
||||
* @param PersistentCollection $coll
|
||||
*/
|
||||
abstract protected function _getInsertRowSql(PersistentCollection $coll);
|
||||
|
||||
|
||||
/**
|
||||
* Gets the SQL parameters for the corresponding SQL statement to insert the given
|
||||
* element of the given collection into the database.
|
||||
*
|
||||
* @param PersistentCollection $coll
|
||||
* @param mixed $element
|
||||
*/
|
||||
abstract protected function _getInsertRowSqlParameters(PersistentCollection $coll, $element);
|
||||
}
|
||||
|
||||
|
@ -21,6 +21,9 @@
|
||||
|
||||
namespace Doctrine\ORM\Persisters;
|
||||
|
||||
use Doctrine\ORM\EntityManager;
|
||||
use Doctrine\ORM\Mapping\ClassMetadata;
|
||||
|
||||
/**
|
||||
* Base class for all EntityPersisters.
|
||||
*
|
||||
@ -65,7 +68,7 @@ abstract class AbstractEntityPersister
|
||||
* that uses the given EntityManager and persists instances of the class described
|
||||
* by the given class metadata descriptor.
|
||||
*/
|
||||
public function __construct(\Doctrine\ORM\EntityManager $em, \Doctrine\ORM\Mapping\ClassMetadata $classMetadata)
|
||||
public function __construct(EntityManager $em, ClassMetadata $classMetadata)
|
||||
{
|
||||
$this->_em = $em;
|
||||
$this->_entityName = $classMetadata->getClassName();
|
||||
@ -112,8 +115,10 @@ abstract class AbstractEntityPersister
|
||||
*/
|
||||
public function delete($entity)
|
||||
{
|
||||
$id = array_combine($this->_classMetadata->getIdentifierFieldNames(),
|
||||
$this->_em->getUnitOfWork()->getEntityIdentifier($entity));
|
||||
$id = array_combine(
|
||||
$this->_classMetadata->getIdentifierFieldNames(),
|
||||
$this->_em->getUnitOfWork()->getEntityIdentifier($entity)
|
||||
);
|
||||
$this->_conn->delete($this->_classMetadata->getTableName(), $id);
|
||||
}
|
||||
|
||||
@ -132,7 +137,7 @@ abstract class AbstractEntityPersister
|
||||
*
|
||||
* @param string $fieldName
|
||||
* @return string
|
||||
* @todo Consider using 'inherited' => 'ClassName' to make the lookup simpler.
|
||||
* @todo Move to ClassMetadata?
|
||||
*/
|
||||
public function getOwningClass($fieldName)
|
||||
{
|
||||
@ -180,11 +185,9 @@ abstract class AbstractEntityPersister
|
||||
if ($this->_classMetadata->hasAssociation($field)) {
|
||||
$assocMapping = $this->_classMetadata->getAssociationMapping($field);
|
||||
if ( ! $assocMapping->isOneToOne() || $assocMapping->isInverseSide()) {
|
||||
//echo "NOT TO-ONE OR INVERSE!";
|
||||
continue;
|
||||
}
|
||||
foreach ($assocMapping->getSourceToTargetKeyColumns() as $sourceColumn => $targetColumn) {
|
||||
//TODO: throw exc if field not set
|
||||
$otherClass = $this->_em->getClassMetadata($assocMapping->getTargetEntityName());
|
||||
if (is_null($newVal)) {
|
||||
$result[$sourceColumn] = null;
|
||||
@ -192,7 +195,6 @@ abstract class AbstractEntityPersister
|
||||
$result[$sourceColumn] = $otherClass->getReflectionProperty(
|
||||
$otherClass->getFieldName($targetColumn))->getValue($newVal);
|
||||
}
|
||||
|
||||
}
|
||||
} else if (is_null($newVal)) {
|
||||
$result[$columnName] = null;
|
||||
|
@ -65,9 +65,7 @@ class ManyToManyPersister extends AbstractCollectionPersister
|
||||
* @override
|
||||
*/
|
||||
protected function _getUpdateRowSql(PersistentCollection $coll)
|
||||
{
|
||||
|
||||
}
|
||||
{}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
@ -96,7 +94,7 @@ class ManyToManyPersister extends AbstractCollectionPersister
|
||||
$this->_uow->getEntityIdentifier($coll->getOwner()),
|
||||
$this->_uow->getEntityIdentifier($element)
|
||||
);
|
||||
var_dump($params);
|
||||
//var_dump($params);
|
||||
return $params;
|
||||
}
|
||||
|
||||
|
@ -23,7 +23,6 @@
|
||||
namespace Doctrine\ORM\Query;
|
||||
|
||||
use Doctrine\ORM\Query\AST;
|
||||
use Doctrine\ORM\Exceptions\QueryException;
|
||||
use Doctrine\ORM\Query\Exec;
|
||||
|
||||
/**
|
||||
|
@ -4,7 +4,7 @@
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
|
||||
namespace Doctrine\ORM\Exceptions;
|
||||
namespace Doctrine\ORM\Query;
|
||||
|
||||
/**
|
||||
* Description of QueryException
|
@ -120,41 +120,35 @@ class UnitOfWork
|
||||
private $_scheduledForDirtyCheck = array();
|
||||
|
||||
/**
|
||||
* A list of all new entities that need to be INSERTed.
|
||||
* A list of all pending entity insertions.
|
||||
*
|
||||
* @var array
|
||||
* @todo Index by class name.
|
||||
* @todo Rename to _inserts?
|
||||
*/
|
||||
private $_newEntities = array();
|
||||
private $_entityInsertions = array();
|
||||
|
||||
/**
|
||||
* A list of all dirty entities that need to be UPDATEd.
|
||||
* A list of all pending entity updates.
|
||||
*
|
||||
* @var array
|
||||
* @todo Rename to _updates?
|
||||
*/
|
||||
private $_dirtyEntities = array();
|
||||
private $_entityUpdates = array();
|
||||
|
||||
/**
|
||||
* A list of all deleted entities.
|
||||
* Removed entities are entities that are "scheduled for removal" but have
|
||||
* not yet been removed from the database.
|
||||
* A list of all pending entity deletions.
|
||||
*
|
||||
* @var array
|
||||
* @todo Rename to _deletions?
|
||||
*/
|
||||
private $_deletedEntities = array();
|
||||
private $_entityDeletions = array();
|
||||
|
||||
/**
|
||||
* All collection deletions.
|
||||
* All pending collection deletions.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $_collectionDeletions = array();
|
||||
|
||||
/**
|
||||
* All collection creations.
|
||||
* All pending collection creations.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
@ -226,9 +220,9 @@ class UnitOfWork
|
||||
// Compute changes done since last commit
|
||||
$this->computeChangeSets();
|
||||
|
||||
if (empty($this->_newEntities) &&
|
||||
empty($this->_deletedEntities) &&
|
||||
empty($this->_dirtyEntities) &&
|
||||
if (empty($this->_entityInsertions) &&
|
||||
empty($this->_entityDeletions) &&
|
||||
empty($this->_entityUpdates) &&
|
||||
empty($this->_collectionUpdates) &&
|
||||
empty($this->_collectionDeletions)) {
|
||||
return; // Nothing to do.
|
||||
@ -267,13 +261,13 @@ class UnitOfWork
|
||||
|
||||
// Take new snapshots from visited collections
|
||||
foreach ($this->_visitedCollections as $coll) {
|
||||
$coll->_takeSnapshot();
|
||||
$coll->takeSnapshot();
|
||||
}
|
||||
|
||||
// Clear up
|
||||
$this->_newEntities = array();
|
||||
$this->_dirtyEntities = array();
|
||||
$this->_deletedEntities = array();
|
||||
$this->_entityInsertions = array();
|
||||
$this->_entityUpdates = array();
|
||||
$this->_entityDeletions = array();
|
||||
$this->_entityChangeSets = array();
|
||||
$this->_collectionUpdates = array();
|
||||
$this->_collectionDeletions = array();
|
||||
@ -341,15 +335,14 @@ class UnitOfWork
|
||||
&& ! ($actualData[$name] instanceof PersistentCollection)) {
|
||||
//TODO: If $actualData[$name] is Collection then unwrap the array
|
||||
$assoc = $class->getAssociationMapping($name);
|
||||
if ($assoc->isOwningSide()) {
|
||||
// Inject PersistentCollection
|
||||
$coll = new PersistentCollection($this->_em, $assoc->getTargetEntityName(),
|
||||
$actualData[$name] ? $actualData[$name] : array());
|
||||
$coll->_setOwner($entity, $assoc);
|
||||
if ( ! $coll->isEmpty()) $coll->setDirty(true);
|
||||
$class->getReflectionProperty($name)->setValue($entity, $coll);
|
||||
$actualData[$name] = $coll;
|
||||
}
|
||||
echo PHP_EOL . "INJECTING PCOLL into $name" . PHP_EOL;
|
||||
// Inject PersistentCollection
|
||||
$coll = new PersistentCollection($this->_em, $assoc->getTargetEntityName(),
|
||||
$actualData[$name] ? $actualData[$name] : array());
|
||||
$coll->setOwner($entity, $assoc);
|
||||
if ( ! $coll->isEmpty()) $coll->setDirty(true);
|
||||
$class->getReflectionProperty($name)->setValue($entity, $coll);
|
||||
$actualData[$name] = $coll;
|
||||
}
|
||||
}
|
||||
|
||||
@ -381,7 +374,7 @@ class UnitOfWork
|
||||
$assoc = $class->getAssociationMapping($propName);
|
||||
if ($assoc->isOneToOne() && $assoc->isOwningSide()) {
|
||||
$entityIsDirty = true;
|
||||
} else if (/*is_null($actualValue) && */$orgValue instanceof PersistentCollection) {
|
||||
} else if ($orgValue instanceof PersistentCollection) {
|
||||
// A PersistentCollection was de-referenced, so delete it.
|
||||
if ( ! in_array($orgValue, $this->_collectionDeletions, true)) {
|
||||
$this->_collectionDeletions[] = $orgValue;
|
||||
@ -394,7 +387,7 @@ class UnitOfWork
|
||||
}
|
||||
if ($changeSet) {
|
||||
if ($entityIsDirty) {
|
||||
$this->_dirtyEntities[$oid] = $entity;
|
||||
$this->_entityUpdates[$oid] = $entity;
|
||||
}
|
||||
$this->_entityChangeSets[$oid] = $changeSet;
|
||||
$this->_originalEntityData[$oid] = $actualData;
|
||||
@ -418,19 +411,28 @@ class UnitOfWork
|
||||
/**
|
||||
* Computes the changes of an association.
|
||||
*
|
||||
* @param <type> $assoc
|
||||
* @param <type> $value
|
||||
* @param AssociationMapping $assoc
|
||||
* @param mixed $value The value of the association.
|
||||
*/
|
||||
private function _computeAssociationChanges($assoc, $value)
|
||||
{
|
||||
/*if ( ! $assoc->isCascadeSave()) {
|
||||
return; // "Persistence by reachability" only if save cascade enabled
|
||||
}*/
|
||||
if ($value instanceof PersistentCollection && $value->isDirty()) {
|
||||
if ($assoc->isOwningSide()) {
|
||||
$this->_collectionUpdates[] = $value;
|
||||
}
|
||||
$this->_visitedCollections[] = $value;
|
||||
}
|
||||
|
||||
if ( ! $assoc->isCascadeSave()) {
|
||||
echo "NOT CASCADING INTO " . $assoc->getSourceFieldName() . PHP_EOL;
|
||||
return; // "Persistence by reachability" only if save cascade specified
|
||||
}
|
||||
|
||||
// Look through the entities, and in any of their associations, for transient
|
||||
// enities, recursively. ("Persistence by reachability")
|
||||
if ($assoc->isOneToOne()) {
|
||||
$value = array($value);
|
||||
}
|
||||
|
||||
$targetClass = $this->_em->getClassMetadata($assoc->getTargetEntityName());
|
||||
foreach ($value as $entry) {
|
||||
$state = $this->getEntityState($entry);
|
||||
@ -450,28 +452,21 @@ class UnitOfWork
|
||||
$this->addToIdentityMap($entry);
|
||||
}
|
||||
|
||||
// NEW entities are INSERTed within the current unit of work.
|
||||
// Collect the original data and changeset, recursing into associations.
|
||||
$data = array();
|
||||
$changeSet = array();
|
||||
foreach ($targetClass->getReflectionProperties() as $name => $refProp) {
|
||||
$data[$name] = $refProp->getValue($entry);
|
||||
$changeSet[$name] = array(null, $data[$name]);
|
||||
// --
|
||||
/*if ($targetClass->isCollectionValuedAssociation($name) && ! ($data[$name] instanceof PersistentCollection)) {
|
||||
// Inject PersistentCollection
|
||||
//TODO: If $actualData[$name] is Collection then unwrap the array
|
||||
$assoc = $targetClass->getAssociationMapping($name);
|
||||
$coll = new PersistentCollection($this->_em, $assoc->getTargetEntityName(),
|
||||
$data[$name] ? $data[$name] : array());
|
||||
$coll->_setOwner($entry, $assoc);
|
||||
if ( ! $coll->isEmpty()) $coll->setDirty(true);
|
||||
$targetClass->getReflectionProperty($name)->setValue($entry, $coll);
|
||||
$data[$name] = $coll;
|
||||
}*/
|
||||
//--
|
||||
if ($targetClass->hasAssociation($name)) {
|
||||
//echo "RECURSING INTO $name" . PHP_EOL;
|
||||
//TODO: Prevent infinite recursion
|
||||
$this->_computeAssociationChanges($targetClass->getAssociationMapping($name), $data[$name]);
|
||||
}
|
||||
}
|
||||
|
||||
$this->_newEntities[$oid] = $entry;
|
||||
// NEW entities are INSERTed within the current unit of work.
|
||||
$this->_entityInsertions[$oid] = $entry;
|
||||
$this->_entityChangeSets[$oid] = $changeSet;
|
||||
$this->_originalEntityData[$oid] = $data;
|
||||
} else if ($state == self::STATE_DELETED) {
|
||||
@ -480,13 +475,6 @@ class UnitOfWork
|
||||
// MANAGED associated entities are already taken into account
|
||||
// during changeset calculation anyway, since they are in the identity map.
|
||||
}
|
||||
|
||||
if ($value instanceof PersistentCollection && $value->isDirty()) {
|
||||
if ($assoc->isOwningSide()) {
|
||||
$this->_collectionUpdates[] = $value;
|
||||
}
|
||||
$this->_visitedCollections[] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -502,7 +490,7 @@ class UnitOfWork
|
||||
// Same for update/delete.
|
||||
$className = $class->getClassName();
|
||||
$persister = $this->getEntityPersister($className);
|
||||
foreach ($this->_newEntities as $entity) {
|
||||
foreach ($this->_entityInsertions as $entity) {
|
||||
if (get_class($entity) == $className) {
|
||||
$returnVal = $persister->insert($entity);
|
||||
if ( ! is_null($returnVal)) {
|
||||
@ -528,7 +516,7 @@ class UnitOfWork
|
||||
{
|
||||
$className = $class->getClassName();
|
||||
$persister = $this->getEntityPersister($className);
|
||||
foreach ($this->_dirtyEntities as $entity) {
|
||||
foreach ($this->_entityUpdates as $entity) {
|
||||
if (get_class($entity) == $className) {
|
||||
$persister->update($entity);
|
||||
}
|
||||
@ -544,7 +532,7 @@ class UnitOfWork
|
||||
{
|
||||
$className = $class->getClassName();
|
||||
$persister = $this->getEntityPersister($className);
|
||||
foreach ($this->_deletedEntities as $entity) {
|
||||
foreach ($this->_entityDeletions as $entity) {
|
||||
if (get_class($entity) == $className) {
|
||||
$persister->delete($entity);
|
||||
}
|
||||
@ -557,12 +545,12 @@ class UnitOfWork
|
||||
* @return array
|
||||
*/
|
||||
private function _getCommitOrder(array $entityChangeSet = null)
|
||||
{
|
||||
{
|
||||
if (is_null($entityChangeSet)) {
|
||||
$entityChangeSet = array_merge(
|
||||
$this->_newEntities,
|
||||
$this->_dirtyEntities,
|
||||
$this->_deletedEntities);
|
||||
$this->_entityInsertions,
|
||||
$this->_entityUpdates,
|
||||
$this->_entityDeletions);
|
||||
}
|
||||
|
||||
// TODO: We can cache computed commit orders in the metadata cache!
|
||||
@ -590,7 +578,7 @@ class UnitOfWork
|
||||
if ($assocMapping->isOwningSide()) {
|
||||
$targetClass = $this->_em->getClassMetadata($assocMapping->getTargetEntityName());
|
||||
$targetClassName = $targetClass->getClassName();
|
||||
// if the target class does not yet have a node, create it
|
||||
// If the target class does not yet have a node, create it
|
||||
if ( ! $this->_commitOrderCalculator->hasNodeWithKey($targetClassName)) {
|
||||
$this->_commitOrderCalculator->addNodeWithItem(
|
||||
$targetClassName, // index/key
|
||||
@ -616,17 +604,17 @@ class UnitOfWork
|
||||
{
|
||||
$oid = spl_object_hash($entity);
|
||||
|
||||
if (isset($this->_dirtyEntities[$oid])) {
|
||||
if (isset($this->_entityUpdates[$oid])) {
|
||||
throw new DoctrineException("Dirty object can't be registered as new.");
|
||||
}
|
||||
if (isset($this->_deletedEntities[$oid])) {
|
||||
if (isset($this->_entityDeletions[$oid])) {
|
||||
throw new DoctrineException("Removed object can't be registered as new.");
|
||||
}
|
||||
if (isset($this->_newEntities[$oid])) {
|
||||
if (isset($this->_entityInsertions[$oid])) {
|
||||
throw new DoctrineException("Object already registered as new. Can't register twice.");
|
||||
}
|
||||
|
||||
$this->_newEntities[$oid] = $entity;
|
||||
$this->_entityInsertions[$oid] = $entity;
|
||||
if (isset($this->_entityIdentifiers[$oid])) {
|
||||
$this->addToIdentityMap($entity);
|
||||
}
|
||||
@ -641,7 +629,7 @@ class UnitOfWork
|
||||
*/
|
||||
public function isRegisteredNew($entity)
|
||||
{
|
||||
return isset($this->_newEntities[spl_object_hash($entity)]);
|
||||
return isset($this->_entityInsertions[spl_object_hash($entity)]);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -657,12 +645,12 @@ class UnitOfWork
|
||||
throw new DoctrineException("Entity without identity "
|
||||
. "can't be registered as dirty.");
|
||||
}
|
||||
if (isset($this->_deletedEntities[$oid])) {
|
||||
if (isset($this->_entityDeletions[$oid])) {
|
||||
throw new DoctrineException("Removed object can't be registered as dirty.");
|
||||
}
|
||||
|
||||
if ( ! isset($this->_dirtyEntities[$oid]) && ! isset($this->_newEntities[$oid])) {
|
||||
$this->_dirtyEntities[$oid] = $entity;
|
||||
if ( ! isset($this->_entityUpdates[$oid]) && ! isset($this->_entityInsertions[$oid])) {
|
||||
$this->_entityUpdates[$oid] = $entity;
|
||||
}
|
||||
}
|
||||
|
||||
@ -677,7 +665,7 @@ class UnitOfWork
|
||||
*/
|
||||
public function isRegisteredDirty($entity)
|
||||
{
|
||||
return isset($this->_dirtyEntities[spl_object_hash($entity)]);
|
||||
return isset($this->_entityUpdates[spl_object_hash($entity)]);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -695,16 +683,16 @@ class UnitOfWork
|
||||
$this->removeFromIdentityMap($entity);
|
||||
$className = get_class($entity);
|
||||
|
||||
if (isset($this->_newEntities[$oid])) {
|
||||
unset($this->_newEntities[$oid]);
|
||||
if (isset($this->_entityInsertions[$oid])) {
|
||||
unset($this->_entityInsertions[$oid]);
|
||||
return; // entity has not been persisted yet, so nothing more to do.
|
||||
}
|
||||
|
||||
if (isset($this->_dirtyEntities[$oid])) {
|
||||
unset($this->_dirtyEntities[$oid]);
|
||||
if (isset($this->_entityUpdates[$oid])) {
|
||||
unset($this->_entityUpdates[$oid]);
|
||||
}
|
||||
if ( ! isset($this->_deletedEntities[$oid])) {
|
||||
$this->_deletedEntities[$oid] = $entity;
|
||||
if ( ! isset($this->_entityDeletions[$oid])) {
|
||||
$this->_entityDeletions[$oid] = $entity;
|
||||
}
|
||||
}
|
||||
|
||||
@ -718,7 +706,7 @@ class UnitOfWork
|
||||
*/
|
||||
public function isRegisteredRemoved($entity)
|
||||
{
|
||||
return isset($this->_deletedEntities[spl_object_hash($entity)]);
|
||||
return isset($this->_entityDeletions[spl_object_hash($entity)]);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -732,8 +720,8 @@ class UnitOfWork
|
||||
{
|
||||
$oid = spl_object_hash($entity);
|
||||
$this->removeFromIdentityMap($entity);
|
||||
unset($this->_newEntities[$oid], $this->_dirtyEntities[$oid],
|
||||
$this->_deletedEntities[$oid], $this->_entityIdentifiers[$oid],
|
||||
unset($this->_entityInsertions[$oid], $this->_entityUpdates[$oid],
|
||||
$this->_entityDeletions[$oid], $this->_entityIdentifiers[$oid],
|
||||
$this->_entityStates[$oid]);
|
||||
}
|
||||
|
||||
@ -747,9 +735,9 @@ class UnitOfWork
|
||||
public function isEntityRegistered($entity)
|
||||
{
|
||||
$oid = spl_object_hash($entity);
|
||||
return isset($this->_newEntities[$oid]) ||
|
||||
isset($this->_dirtyEntities[$oid]) ||
|
||||
isset($this->_deletedEntities[$oid]);
|
||||
return isset($this->_entityInsertions[$oid]) ||
|
||||
isset($this->_entityUpdates[$oid]) ||
|
||||
isset($this->_entityDeletions[$oid]);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -774,9 +762,9 @@ class UnitOfWork
|
||||
} else {
|
||||
$numDetached = count($this->_identityMap);
|
||||
$this->_identityMap = array();
|
||||
$this->_newEntities = array();
|
||||
$this->_dirtyEntities = array();
|
||||
$this->_deletedEntities = array();
|
||||
$this->_entityInsertions = array();
|
||||
$this->_entityUpdates = array();
|
||||
$this->_entityDeletions = array();
|
||||
}
|
||||
|
||||
return $numDetached;
|
||||
@ -817,7 +805,7 @@ class UnitOfWork
|
||||
{
|
||||
$oid = spl_object_hash($entity);
|
||||
if ( ! isset($this->_entityStates[$oid])) {
|
||||
if (isset($this->_entityIdentifiers[$oid]) && ! isset($this->_newEntities[$oid])) {
|
||||
if (isset($this->_entityIdentifiers[$oid]) && ! isset($this->_entityInsertions[$oid])) {
|
||||
$this->_entityStates[$oid] = self::STATE_DETACHED;
|
||||
} else {
|
||||
$this->_entityStates[$oid] = self::STATE_NEW;
|
||||
@ -951,8 +939,8 @@ class UnitOfWork
|
||||
foreach ($commitOrder as $class) {
|
||||
$this->_executeInserts($class);
|
||||
}
|
||||
// remove them from _newEntities and _entityChangeSets
|
||||
$this->_newEntities = array_diff_key($this->_newEntities, $insertNow);
|
||||
// remove them from _entityInsertions and _entityChangeSets
|
||||
$this->_entityInsertions = array_diff_key($this->_entityInsertions, $insertNow);
|
||||
$this->_entityChangeSets = array_diff_key($this->_entityChangeSets, $insertNow);
|
||||
}
|
||||
}
|
||||
@ -1007,7 +995,7 @@ class UnitOfWork
|
||||
// entity becomes managed again
|
||||
if ($this->isRegisteredRemoved($entity)) {
|
||||
//TODO: better a method for this?
|
||||
unset($this->_deletedEntities[$oid]);
|
||||
unset($this->_entityDeletions[$oid]);
|
||||
} else {
|
||||
//FIXME: There's more to think of here...
|
||||
$this->registerNew($entity);
|
||||
@ -1384,8 +1372,4 @@ class UnitOfWork
|
||||
}
|
||||
return $this->_collectionPersisters[$type];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
@ -1,5 +1,27 @@
|
||||
<?php
|
||||
#namespace Doctrine\ORM;
|
||||
/*
|
||||
* $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.doctrine-project.org>.
|
||||
*/
|
||||
|
||||
namespace Doctrine\ORM;
|
||||
|
||||
use Doctrine\ORM\Mapping\AssociationMapping;
|
||||
|
||||
/**
|
||||
* Represents a virtual proxy that is used for lazy to-one associations.
|
||||
@ -7,7 +29,7 @@
|
||||
* @author robo
|
||||
* @since 2.0
|
||||
*/
|
||||
class Doctrine_ORM_VirtualProxy
|
||||
class VirtualProxy
|
||||
{
|
||||
private $_assoc;
|
||||
private $_refProp;
|
||||
@ -22,7 +44,7 @@ class Doctrine_ORM_VirtualProxy
|
||||
* @param <type> $assoc
|
||||
* @param <type> $refProp
|
||||
*/
|
||||
public function __construct($owner, Doctrine_ORM_Mapping_AssociationMapping $assoc, ReflectionProperty $refProp)
|
||||
public function __construct($owner, AssociationMapping $assoc, \ReflectionProperty $refProp)
|
||||
{
|
||||
$this->_owner = $owner;
|
||||
$this->_assoc = $assoc;
|
||||
|
@ -10,9 +10,6 @@ if (!defined('PHPUnit_MAIN_METHOD')) {
|
||||
|
||||
require_once __DIR__ . '/../TestInit.php';
|
||||
|
||||
// Suites
|
||||
#require_once 'Common/Collections/AllTests.php';
|
||||
|
||||
class AllTests
|
||||
{
|
||||
public static function main()
|
||||
@ -24,6 +21,8 @@ class AllTests
|
||||
{
|
||||
$suite = new \Doctrine\Tests\DoctrineTestSuite('Doctrine Common Tests');
|
||||
|
||||
$suite->addTestSuite('Doctrine\Tests\Common\EventManagerTest');
|
||||
|
||||
$suite->addTest(Collections\AllTests::suite());
|
||||
|
||||
return $suite;
|
||||
|
72
tests/Doctrine/Tests/Common/EventManagerTest.php
Normal file
72
tests/Doctrine/Tests/Common/EventManagerTest.php
Normal file
@ -0,0 +1,72 @@
|
||||
<?php
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
|
||||
namespace Doctrine\Tests\Common;
|
||||
|
||||
use Doctrine\Common\EventManager;
|
||||
use Doctrine\Common\EventArgs;
|
||||
|
||||
/**
|
||||
* Description of EventManagerTest
|
||||
*
|
||||
* @author robo
|
||||
*/
|
||||
class EventManagerTest extends \Doctrine\Tests\DoctrineTestCase
|
||||
{
|
||||
/* Some pseudo events */
|
||||
const preFoo = 'preFoo';
|
||||
const postFoo = 'postFoo';
|
||||
|
||||
private $_preFooInvoked = false;
|
||||
private $_postFooInvoked = false;
|
||||
|
||||
private $_eventManager;
|
||||
|
||||
protected function setUp() {
|
||||
$this->_eventManager = new EventManager;
|
||||
$this->_preFooInvoked = false;
|
||||
$this->_postFooInvoked = false;
|
||||
}
|
||||
|
||||
public function testInitialState()
|
||||
{
|
||||
$this->assertEquals(array(), $this->_eventManager->getListeners());
|
||||
$this->assertFalse($this->_eventManager->hasListeners(self::preFoo));
|
||||
$this->assertFalse($this->_eventManager->hasListeners(self::postFoo));
|
||||
}
|
||||
|
||||
public function testAddEventListener()
|
||||
{
|
||||
$this->_eventManager->addEventListener(array('preFoo', 'postFoo'), $this);
|
||||
$this->assertTrue($this->_eventManager->hasListeners(self::preFoo));
|
||||
$this->assertTrue($this->_eventManager->hasListeners(self::postFoo));
|
||||
$this->assertEquals(1, count($this->_eventManager->getListeners(self::preFoo)));
|
||||
$this->assertEquals(1, count($this->_eventManager->getListeners(self::postFoo)));
|
||||
$this->assertEquals(2, count($this->_eventManager->getListeners()));
|
||||
}
|
||||
|
||||
public function testDispatchEvent()
|
||||
{
|
||||
$this->_eventManager->addEventListener(array('preFoo', 'postFoo'), $this);
|
||||
$this->_eventManager->dispatchEvent(self::preFoo);
|
||||
$this->assertTrue($this->_preFooInvoked);
|
||||
$this->assertFalse($this->_postFooInvoked);
|
||||
}
|
||||
|
||||
|
||||
/* Listener methods */
|
||||
|
||||
public function preFoo(EventArgs $e)
|
||||
{
|
||||
$this->_preFooInvoked = true;
|
||||
}
|
||||
|
||||
public function postFoo(EventArgs $e)
|
||||
{
|
||||
$this->_postFooInvoked = true;
|
||||
}
|
||||
}
|
||||
|
@ -39,7 +39,7 @@ class CmsUser
|
||||
*/
|
||||
public $address;
|
||||
/**
|
||||
* @DoctrineManyToMany(targetEntity="CmsGroup")
|
||||
* @DoctrineManyToMany(targetEntity="CmsGroup", cascade={"save"})
|
||||
* @DoctrineJoinTable(name="cms_users_groups",
|
||||
joinColumns={{"name"="user_id", "referencedColumnName"="id"}},
|
||||
inverseJoinColumns={{"name"="group_id", "referencedColumnName"="id"}})
|
||||
|
@ -22,7 +22,7 @@ class EntityManagerTest extends \Doctrine\Tests\OrmTestCase
|
||||
try {
|
||||
$this->_em->setFlushMode('foobar');
|
||||
$this->fail("Setting invalid flushmode did not trigger exception.");
|
||||
} catch (\Doctrine\ORM\Exceptions\EntityManagerException $expected) {}
|
||||
} catch (\Doctrine\ORM\EntityManagerException $expected) {}
|
||||
$this->_em->setFlushMode($prev);
|
||||
}
|
||||
}
|
@ -157,6 +157,8 @@ class BasicCRUDTest extends \Doctrine\Tests\OrmFunctionalTestCase {
|
||||
|
||||
public function testManyToManyCollectionClearing()
|
||||
{
|
||||
echo PHP_EOL . "MANY-MANY" . PHP_EOL;
|
||||
|
||||
$user = new CmsUser;
|
||||
$user->name = 'Guilherme';
|
||||
$user->username = 'gblanco';
|
||||
@ -171,11 +173,17 @@ class BasicCRUDTest extends \Doctrine\Tests\OrmFunctionalTestCase {
|
||||
|
||||
$this->_em->save($user); // Saves the user, cause of post-insert ID
|
||||
|
||||
$this->_em->flush(); // Saves the groups, cause they're attached to a persistent entity ($user)
|
||||
$this->_em->flush();
|
||||
|
||||
// Check that there are indeed 10 links in the association table
|
||||
$count = $this->_em->getConnection()->execute("SELECT COUNT(*) FROM cms_users_groups",
|
||||
array())->fetchColumn();
|
||||
$this->assertEquals(10, $count);
|
||||
|
||||
//$user->groups->clear();
|
||||
unset($user->groups);
|
||||
|
||||
echo PHP_EOL . "FINAL FLUSH" . PHP_EOL;
|
||||
$this->_em->flush();
|
||||
|
||||
// Check that the links in the association table have been deleted
|
||||
|
@ -89,7 +89,7 @@ class SingleScalarHydratorTest extends HydrationTest
|
||||
$result = $hydrator->hydrateall($stmt, $this->_createParserResult(
|
||||
$queryComponents, $tableAliasMap));
|
||||
$this->fail();
|
||||
} catch (\Doctrine\ORM\Exceptions\HydrationException $ex) {}
|
||||
} catch (\Doctrine\ORM\Internal\Hydration\HydrationException $ex) {}
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user