commit
bf91d03adf
@ -38,3 +38,5 @@ matrix:
|
||||
env: DB=pgsql # driver currently unsupported by HHVM
|
||||
- php: hhvm-nightly
|
||||
env: DB=mysqli # driver currently unsupported by HHVM
|
||||
allow_failures:
|
||||
- php: hhvm-nightly # hhvm-nightly currently chokes on composer installation
|
||||
|
10
UPGRADE.md
10
UPGRADE.md
@ -2,17 +2,17 @@
|
||||
|
||||
## Minor BC BREAK: Custom Hydrators API change
|
||||
|
||||
As of 2.5, `AbstractHydrator` does not enforce the usage of cache as part of
|
||||
As of 2.5, `AbstractHydrator` does not enforce the usage of cache as part of
|
||||
API, and now provides you a clean API for column information through the method
|
||||
`hydrateColumnInfo($column)`.
|
||||
Cache variable being passed around by reference is no longer needed since
|
||||
Cache variable being passed around by reference is no longer needed since
|
||||
Hydrators are per query instantiated since Doctrine 2.4.
|
||||
|
||||
## Minor BC BREAK: Entity based ``EntityManager#clear()`` calls follow cascade detach
|
||||
|
||||
Whenever ``EntityManager#clear()`` method gets called with a given entity class
|
||||
name, until 2.4, it was only detaching the specific requested entity.
|
||||
As of 2.5, ``EntityManager`` will follow configured cascades, providing a better
|
||||
Whenever ``EntityManager#clear()`` method gets called with a given entity class
|
||||
name, until 2.4, it was only detaching the specific requested entity.
|
||||
As of 2.5, ``EntityManager`` will follow configured cascades, providing a better
|
||||
memory management since associations will be garbage collected, optimizing
|
||||
resources consumption on long running jobs.
|
||||
|
||||
|
@ -20,7 +20,14 @@
|
||||
use Symfony\Component\Console\Helper\HelperSet;
|
||||
use Doctrine\ORM\Tools\Console\ConsoleRunner;
|
||||
|
||||
(@include_once __DIR__ . '/../vendor/autoload.php') || @include_once __DIR__ . '/../../../autoload.php';
|
||||
$autoloadFiles = array(__DIR__ . '/../vendor/autoload.php',
|
||||
__DIR__ . '/../../../autoload.php');
|
||||
|
||||
foreach ($autoloadFiles as $autoloadFile) {
|
||||
if (file_exists($autoloadFile)) {
|
||||
require_once $autoloadFile;
|
||||
}
|
||||
}
|
||||
|
||||
$directories = array(getcwd(), getcwd() . DIRECTORY_SEPARATOR . 'config');
|
||||
|
||||
|
@ -232,7 +232,7 @@ Example usage
|
||||
// Setup custom mapping type
|
||||
use Doctrine\DBAL\Types\Type;
|
||||
|
||||
Type::addType('point', 'Geo\Types\Point');
|
||||
Type::addType('point', 'Geo\Types\PointType');
|
||||
$em->getConnection()->getDatabasePlatform()->registerDoctrineTypeMapping('point', 'point');
|
||||
|
||||
// Store a Location object
|
||||
|
@ -3,7 +3,7 @@ Keeping your Modules independent
|
||||
|
||||
.. versionadded:: 2.2
|
||||
|
||||
One of the goals of using modules is to create discreet units of functionality
|
||||
One of the goals of using modules is to create discrete units of functionality
|
||||
that do not have many (if any) dependencies, allowing you to use that
|
||||
functionality in other applications without including unnecessary items.
|
||||
|
||||
|
@ -109,6 +109,26 @@ Optional attributes:
|
||||
|
||||
- **nullable**: Determines if NULL values allowed for this column.
|
||||
|
||||
- **options**: Array of additional options:
|
||||
|
||||
- ``default``: The default value to set for the column if no value
|
||||
is supplied.
|
||||
|
||||
- ``unsigned``: Boolean value to determine if the column should
|
||||
be capable of representing only non-negative integers
|
||||
(applies only for integer column and might not be supported by
|
||||
all vendors).
|
||||
|
||||
- ``fixed``: Boolean value to determine if the specified length of
|
||||
a string column should be fixed or varying (applies only for
|
||||
string/binary column and might not be supported by all vendors).
|
||||
|
||||
- ``comment``: The comment of the column in the schema (might not
|
||||
be supported by all vendors).
|
||||
|
||||
- ``customSchemaOptions``: Array of additional schema options
|
||||
which are mostly vendor specific.
|
||||
|
||||
- **columnDefinition**: DDL SQL snippet that starts after the column
|
||||
name and specifies the complete (non-portable!) column definition.
|
||||
This attribute allows to make use of advanced RMDBS features.
|
||||
@ -120,7 +140,12 @@ Optional attributes:
|
||||
attribute still handles the conversion between PHP and Database
|
||||
values. If you use this attribute on a column that is used for
|
||||
joins between tables you should also take a look at
|
||||
:ref:`@JoinColumn <annref_joincolumn>`.
|
||||
:ref:`@JoinColumn <annref_joincolumn>`.
|
||||
|
||||
.. note::
|
||||
|
||||
For more detailed information on each attribute, please refer to
|
||||
the DBAL ``Schema-Representation`` documentation.
|
||||
|
||||
Examples:
|
||||
|
||||
@ -131,17 +156,27 @@ Examples:
|
||||
* @Column(type="string", length=32, unique=true, nullable=false)
|
||||
*/
|
||||
protected $username;
|
||||
|
||||
|
||||
/**
|
||||
* @Column(type="string", columnDefinition="CHAR(2) NOT NULL")
|
||||
*/
|
||||
protected $country;
|
||||
|
||||
|
||||
/**
|
||||
* @Column(type="decimal", precision=2, scale=1)
|
||||
*/
|
||||
protected $height;
|
||||
|
||||
/**
|
||||
* @Column(type="string", length=2, options={"fixed":true, "comment":"Initial letters of first and last name"})
|
||||
*/
|
||||
protected $initials;
|
||||
|
||||
/**
|
||||
* @Column(type="integer", name="login_count" nullable=false, options={"unsigned":true, "default":0})
|
||||
*/
|
||||
protected $loginCount;
|
||||
|
||||
.. _annref_column_result:
|
||||
|
||||
@ColumnResult
|
||||
@ -222,7 +257,7 @@ Optional attributes:
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The discriminator map is a required annotation on the
|
||||
topmost/super class in an inheritance hierarchy. Its only argument is an
|
||||
topmost/super class in an inheritance hierarchy. Its only argument is an
|
||||
array which defines which class should be saved under
|
||||
which name in the database. Keys are the database value and values
|
||||
are the classes, either as fully- or as unqualified class names
|
||||
@ -447,7 +482,7 @@ Examples:
|
||||
{
|
||||
// ...
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @Entity
|
||||
* @InheritanceType("JOINED")
|
||||
@ -612,7 +647,7 @@ Optional attributes:
|
||||
- **mappedBy**: This option specifies the property name on the
|
||||
targetEntity that is the owning side of this relation. It is a
|
||||
required attribute for the inverse side of a relationship.
|
||||
- **inversedBy**: The inversedBy attribute designates the field in the
|
||||
- **inversedBy**: The inversedBy attribute designates the field in the
|
||||
entity that is the inverse side of the relationship.
|
||||
- **cascade**: Cascade Option
|
||||
- **fetch**: One of LAZY, EXTRA_LAZY or EAGER
|
||||
@ -640,7 +675,7 @@ Example:
|
||||
* )
|
||||
*/
|
||||
private $groups;
|
||||
|
||||
|
||||
/**
|
||||
* Inverse Side
|
||||
*
|
||||
@ -786,7 +821,7 @@ Optional attributes:
|
||||
- **orphanRemoval**: Boolean that specifies if orphans, inverse
|
||||
OneToOne entities that are not connected to any owning instance,
|
||||
should be removed by Doctrine. Defaults to false.
|
||||
- **inversedBy**: The inversedBy attribute designates the field in the
|
||||
- **inversedBy**: The inversedBy attribute designates the field in the
|
||||
entity that is the inverse side of the relationship.
|
||||
|
||||
Example:
|
||||
|
@ -42,6 +42,8 @@ internally but also mean more work during ``flush``.
|
||||
$em->clear(); // Detaches all objects from Doctrine!
|
||||
}
|
||||
}
|
||||
$em->flush(); //Persist objects that did not make up an entire batch
|
||||
$em->clear();
|
||||
|
||||
Bulk Updates
|
||||
------------
|
||||
|
@ -302,6 +302,14 @@ With Arithmetic Expression in WHERE clause:
|
||||
$query = $em->createQuery('SELECT u FROM CmsUser u WHERE ((u.id + 5000) * u.id + 3) < 10000000');
|
||||
$users = $query->getResult(); // array of ForumUser objects
|
||||
|
||||
Retrieve user entities with Arithmetic Expression in ORDER close, using the ``HIDDEN`` keyword:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$query = $em->createQuery('SELECT u, u.posts_count + u.likes_count AS HIDDEN score FROM CmsUser u ORDER BY score');
|
||||
$users = $query->getResult(); // array of User objects
|
||||
|
||||
Using a LEFT JOIN to hydrate all user-ids and optionally associated
|
||||
article-ids:
|
||||
|
||||
|
@ -191,6 +191,12 @@ the life-time of their registered entities.
|
||||
safe to access associations in a postLoad callback or event
|
||||
handler.
|
||||
|
||||
.. warning::
|
||||
|
||||
Note that the postRemove event or any events triggered after an entity removal
|
||||
can receive an uninitializable proxy in case you have configured an entity to
|
||||
cascade remove relations. In this case, you should load yourself the proxy in
|
||||
the associated pre event.
|
||||
|
||||
You can access the Event constants from the ``Events`` class in the
|
||||
ORM package.
|
||||
|
@ -109,19 +109,19 @@ Example:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
MyProject\Model\Person:
|
||||
type: entity
|
||||
inheritanceType: SINGLE_TABLE
|
||||
discriminatorColumn:
|
||||
MyProject\Model\Person:
|
||||
type: entity
|
||||
inheritanceType: SINGLE_TABLE
|
||||
discriminatorColumn:
|
||||
name: discr
|
||||
type: string
|
||||
discriminatorMap:
|
||||
discriminatorMap:
|
||||
person: Person
|
||||
employee: Employee
|
||||
|
||||
MyProject\Model\Employee:
|
||||
type: entity
|
||||
|
||||
MyProject\Model\Employee:
|
||||
type: entity
|
||||
|
||||
Things to note:
|
||||
|
||||
|
||||
|
@ -65,18 +65,6 @@ Where the ``attribute_name`` column contains the key and
|
||||
The feature request for persistence of primitive value arrays
|
||||
`is described in the DDC-298 ticket <http://www.doctrine-project.org/jira/browse/DDC-298>`_.
|
||||
|
||||
Value Objects
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
There is currently no native support value objects in Doctrine
|
||||
other than for ``DateTime`` instances or if you serialize the
|
||||
objects using ``serialize()/deserialize()`` which the DBAL Type
|
||||
"object" supports.
|
||||
|
||||
The feature request for full value-object support
|
||||
`is described in the DDC-93 ticket <http://www.doctrine-project.org/jira/browse/DDC-93>`_.
|
||||
|
||||
|
||||
Cascade Merge with Bi-directional Associations
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
|
@ -27,7 +27,7 @@ to write a mapping file for it using the above configured
|
||||
|
||||
<?php
|
||||
namespace Entities;
|
||||
|
||||
|
||||
class User
|
||||
{
|
||||
private $id;
|
||||
@ -42,16 +42,30 @@ named ``Entities.User.php`` inside of the
|
||||
|
||||
<?php
|
||||
// /path/to/php/mapping/files/Entities.User.php
|
||||
|
||||
|
||||
$metadata->mapField(array(
|
||||
'id' => true,
|
||||
'fieldName' => 'id',
|
||||
'type' => 'integer'
|
||||
));
|
||||
|
||||
|
||||
$metadata->mapField(array(
|
||||
'fieldName' => 'username',
|
||||
'type' => 'string'
|
||||
'type' => 'string',
|
||||
'options' => array(
|
||||
'fixed' => true,
|
||||
'comment' => "User's login name"
|
||||
)
|
||||
));
|
||||
|
||||
$metadata->mapField(array(
|
||||
'fieldName' => 'login_count',
|
||||
'type' => 'integer',
|
||||
'nullable' => false,
|
||||
'options' => array(
|
||||
'unsigned' => true,
|
||||
'default' => 0
|
||||
)
|
||||
));
|
||||
|
||||
Now we can easily retrieve the populated ``ClassMetadata`` instance
|
||||
@ -87,13 +101,13 @@ Now you just need to define a static function named
|
||||
|
||||
<?php
|
||||
namespace Entities;
|
||||
|
||||
|
||||
use Doctrine\ORM\Mapping\ClassMetadata;
|
||||
|
||||
|
||||
class User
|
||||
{
|
||||
// ...
|
||||
|
||||
|
||||
public static function loadMetadata(ClassMetadata $metadata)
|
||||
{
|
||||
$metadata->mapField(array(
|
||||
@ -101,7 +115,7 @@ Now you just need to define a static function named
|
||||
'fieldName' => 'id',
|
||||
'type' => 'integer'
|
||||
));
|
||||
|
||||
|
||||
$metadata->mapField(array(
|
||||
'fieldName' => 'username',
|
||||
'type' => 'string'
|
||||
|
@ -22,9 +22,9 @@ setup for the latest code in trunk.
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping
|
||||
https://raw.github.com/doctrine/doctrine2/master/doctrine-mapping.xsd">
|
||||
|
||||
|
||||
...
|
||||
|
||||
|
||||
</doctrine-mapping>
|
||||
|
||||
The XML mapping document of a class is loaded on-demand the first
|
||||
@ -108,37 +108,37 @@ of several common elements:
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping
|
||||
http://raw.github.com/doctrine/doctrine2/master/doctrine-mapping.xsd">
|
||||
|
||||
|
||||
<entity name="Doctrine\Tests\ORM\Mapping\User" table="cms_users">
|
||||
|
||||
|
||||
<indexes>
|
||||
<index name="name_idx" columns="name"/>
|
||||
<index columns="user_email"/>
|
||||
</indexes>
|
||||
|
||||
|
||||
<unique-constraints>
|
||||
<unique-constraint columns="name,user_email" name="search_idx" />
|
||||
</unique-constraints>
|
||||
|
||||
|
||||
<lifecycle-callbacks>
|
||||
<lifecycle-callback type="prePersist" method="doStuffOnPrePersist"/>
|
||||
<lifecycle-callback type="prePersist" method="doOtherStuffOnPrePersistToo"/>
|
||||
<lifecycle-callback type="postPersist" method="doStuffOnPostPersist"/>
|
||||
</lifecycle-callbacks>
|
||||
|
||||
|
||||
<id name="id" type="integer" column="id">
|
||||
<generator strategy="AUTO"/>
|
||||
<sequence-generator sequence-name="tablename_seq" allocation-size="100" initial-value="1" />
|
||||
</id>
|
||||
|
||||
|
||||
<field name="name" column="name" type="string" length="50" nullable="true" unique="true" />
|
||||
<field name="email" column="user_email" type="string" column-definition="CHAR(32) NOT NULL" />
|
||||
|
||||
|
||||
<one-to-one field="address" target-entity="Address" inversed-by="user">
|
||||
<cascade><cascade-remove /></cascade>
|
||||
<join-column name="address_id" referenced-column-name="id" on-delete="CASCADE" on-update="CASCADE"/>
|
||||
</one-to-one>
|
||||
|
||||
|
||||
<one-to-many field="phonenumbers" target-entity="Phonenumber" mapped-by="user">
|
||||
<cascade>
|
||||
<cascade-persist/>
|
||||
@ -147,7 +147,7 @@ of several common elements:
|
||||
<order-by-field name="number" direction="ASC" />
|
||||
</order-by>
|
||||
</one-to-many>
|
||||
|
||||
|
||||
<many-to-many field="groups" target-entity="Group">
|
||||
<cascade>
|
||||
<cascade-all/>
|
||||
@ -161,9 +161,9 @@ of several common elements:
|
||||
</inverse-join-columns>
|
||||
</join-table>
|
||||
</many-to-many>
|
||||
|
||||
|
||||
</entity>
|
||||
|
||||
|
||||
</doctrine-mapping>
|
||||
|
||||
Be aware that class-names specified in the XML files should be
|
||||
@ -224,12 +224,18 @@ entity. For the ID mapping you have to use the ``<id />`` element.
|
||||
.. code-block:: xml
|
||||
|
||||
<entity name="MyProject\User">
|
||||
|
||||
|
||||
<field name="name" type="string" length="50" />
|
||||
<field name="username" type="string" unique="true" />
|
||||
<field name="age" type="integer" nullable="true" />
|
||||
<field name="isActive" column="is_active" type="boolean" />
|
||||
<field name="weight" type="decimal" scale="5" precision="2" />
|
||||
<field name="login_count" type="integer" nullable="false">
|
||||
<options>
|
||||
<option name="comment">The number of times the user has logged in.</option>
|
||||
<option name="default">0</option>
|
||||
</options>
|
||||
</field>
|
||||
</entity>
|
||||
|
||||
Required attributes:
|
||||
@ -255,12 +261,32 @@ Optional attributes:
|
||||
works on fields with type integer or datetime.
|
||||
- scale - Scale of a decimal type.
|
||||
- precision - Precision of a decimal type.
|
||||
- options - Array of additional options:
|
||||
|
||||
- default - The default value to set for the column if no value
|
||||
is supplied.
|
||||
- unsigned - Boolean value to determine if the column should
|
||||
be capable of representing only non-negative integers
|
||||
(applies only for integer column and might not be supported by
|
||||
all vendors).
|
||||
- fixed - Boolean value to determine if the specified length of
|
||||
a string column should be fixed or varying (applies only for
|
||||
string/binary column and might not be supported by all vendors).
|
||||
- comment - The comment of the column in the schema (might not
|
||||
be supported by all vendors).
|
||||
- customSchemaOptions - Array of additional schema options
|
||||
which are mostly vendor specific.
|
||||
- column-definition - Optional alternative SQL representation for
|
||||
this column. This definition begin after the field-name and has to
|
||||
specify the complete column definition. Using this feature will
|
||||
turn this field dirty for Schema-Tool update commands at all
|
||||
times.
|
||||
|
||||
.. note::
|
||||
|
||||
For more detailed information on each attribute, please refer to
|
||||
the DBAL ``Schema-Representation`` documentation.
|
||||
|
||||
Defining Identity and Generator Strategies
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
@ -423,7 +449,7 @@ using the ``<lifecycle-callbacks />`` element:
|
||||
.. code-block:: xml
|
||||
|
||||
<entity name="Doctrine\Tests\ORM\Mapping\User" table="cms_users">
|
||||
|
||||
|
||||
<lifecycle-callbacks>
|
||||
<lifecycle-callback type="prePersist" method="onPrePersist" />
|
||||
</lifecycle-callbacks>
|
||||
@ -716,12 +742,12 @@ table you can use the ``<indexes />`` and
|
||||
.. code-block:: xml
|
||||
|
||||
<entity name="Doctrine\Tests\ORM\Mapping\User" table="cms_users">
|
||||
|
||||
|
||||
<indexes>
|
||||
<index name="name_idx" columns="name"/>
|
||||
<index columns="user_email"/>
|
||||
</indexes>
|
||||
|
||||
|
||||
<unique-constraints>
|
||||
<unique-constraint columns="name,user_email" name="search_idx" />
|
||||
</unique-constraints>
|
||||
|
@ -94,6 +94,14 @@ of several common elements:
|
||||
unique: true
|
||||
options:
|
||||
fixed: true
|
||||
comment: User's email address
|
||||
loginCount:
|
||||
type: integer
|
||||
column: login_count
|
||||
nullable: false
|
||||
options:
|
||||
unsigned: true
|
||||
default: 0
|
||||
oneToOne:
|
||||
address:
|
||||
targetEntity: Address
|
||||
|
@ -429,7 +429,6 @@
|
||||
<xs:attribute name="unique" type="xs:boolean" default="false" />
|
||||
<xs:attribute name="nullable" type="xs:boolean" default="true" />
|
||||
<xs:attribute name="on-delete" type="orm:fk-action" />
|
||||
<xs:attribute name="on-update" type="orm:fk-action" />
|
||||
<xs:attribute name="column-definition" type="xs:string" />
|
||||
<xs:anyAttribute namespace="##other"/>
|
||||
</xs:complexType>
|
||||
|
@ -191,9 +191,9 @@ abstract class AbstractEntityPersister implements CachedEntityPersister
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function exists($entity, array $extraConditions = array())
|
||||
public function exists($entity, Criteria $extraConditions = null)
|
||||
{
|
||||
if (empty($extraConditions)) {
|
||||
if (null === $extraConditions) {
|
||||
$key = new EntityCacheKey($this->class->rootEntityName, $this->class->getIdentifierValues($entity));
|
||||
|
||||
if ($this->region->contains($key)) {
|
||||
|
@ -425,7 +425,7 @@ use Doctrine\Common\Util\ClassUtils;
|
||||
break;
|
||||
|
||||
case LockMode::NONE === $lockMode:
|
||||
case LockMode::PESSIMISTIC_READ === $lockMode;
|
||||
case LockMode::PESSIMISTIC_READ === $lockMode:
|
||||
case LockMode::PESSIMISTIC_WRITE === $lockMode:
|
||||
$persister = $unitOfWork->getEntityPersister($class->name);
|
||||
$persister->refresh($sortedId, $entity, $lockMode);
|
||||
|
@ -75,6 +75,11 @@ class SimpleObjectHydrator extends AbstractHydrator
|
||||
if ($this->class->inheritanceType !== ClassMetadata::INHERITANCE_TYPE_NONE) {
|
||||
$discrColumnName = $this->_platform->getSQLResultCasing($this->class->discriminatorColumn['name']);
|
||||
|
||||
// Find mapped discriminator column from the result set.
|
||||
if ($metaMappingDiscrColumnName = array_search($discrColumnName, $this->_rsm->metaMappings)) {
|
||||
$discrColumnName = $metaMappingDiscrColumnName;
|
||||
}
|
||||
|
||||
if ( ! isset($sqlResult[$discrColumnName])) {
|
||||
throw HydrationException::missingDiscriminatorColumn($entityName, $discrColumnName, key($this->_rsm->aliasMap));
|
||||
}
|
||||
|
@ -30,7 +30,7 @@ use Doctrine\ORM\Persisters\EntityPersister;
|
||||
* A lazy collection that allow a fast count when using criteria object
|
||||
* Once count gets executed once without collection being initialized, result
|
||||
* is cached and returned on subsequent calls until collection gets loaded,
|
||||
* then returning the number of loaded results.
|
||||
* then returning the number of loaded results.
|
||||
*
|
||||
* @since 2.5
|
||||
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
|
||||
@ -82,6 +82,21 @@ class LazyCriteriaCollection extends AbstractLazyCollection implements Selectabl
|
||||
return $this->count = $this->entityPersister->count($this->criteria);
|
||||
}
|
||||
|
||||
/**
|
||||
* Do an optimized search of an element
|
||||
*
|
||||
* @param object $element
|
||||
* @return bool
|
||||
*/
|
||||
public function contains($element)
|
||||
{
|
||||
if ($this->isInitialized()) {
|
||||
return $this->collection->contains($element);
|
||||
}
|
||||
|
||||
return $this->entityPersister->exists($element, $this->criteria);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
|
@ -908,7 +908,7 @@ class ClassMetadataInfo implements ClassMetadata
|
||||
public function newInstance()
|
||||
{
|
||||
if ($this->_prototype === null) {
|
||||
if (PHP_VERSION_ID === 50428 || PHP_VERSION_ID === 50513) {
|
||||
if (PHP_VERSION_ID === 50429 || PHP_VERSION_ID === 50513) {
|
||||
$this->_prototype = $this->reflClass->newInstanceWithoutConstructor();
|
||||
} else {
|
||||
$this->_prototype = unserialize(sprintf('O:%d:"%s":0:{}', strlen($this->name), $this->name));
|
||||
|
@ -655,7 +655,7 @@ class MappingException extends \Doctrine\ORM\ORMException
|
||||
*/
|
||||
public static function noInheritanceOnMappedSuperClass($className)
|
||||
{
|
||||
return new self("Its not supported to define inheritance information on a mapped superclass '" . $className . "'.");
|
||||
return new self("It is not supported to define inheritance information on a mapped superclass '" . $className . "'.");
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -65,7 +65,7 @@ class ORMInvalidArgumentException extends \InvalidArgumentException
|
||||
static public function entityWithoutIdentity($className, $entity)
|
||||
{
|
||||
return new self(
|
||||
"The given entity of type '" . $className . "' (".self::objToStr($entity).") has no identity/no " .
|
||||
"The given entity of type '" . $className . "' (".self::objToStr($entity).") has no identity/no " .
|
||||
"id values set. It cannot be added to the identity map."
|
||||
);
|
||||
}
|
||||
@ -154,7 +154,7 @@ class ORMInvalidArgumentException extends \InvalidArgumentException
|
||||
*/
|
||||
static public function detachedEntityCannot($entity, $operation)
|
||||
{
|
||||
return new self("A detached entity was found during " . $operation . " " . self::objToStr($entity));
|
||||
return new self("Detached entity " . self::objToStr($entity) . " cannot be " . $operation);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1835,7 +1835,7 @@ class BasicEntityPersister implements EntityPersister
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function exists($entity, array $extraConditions = array())
|
||||
public function exists($entity, Criteria $extraConditions = null)
|
||||
{
|
||||
$criteria = $this->class->getIdentifierValues($entity);
|
||||
|
||||
@ -1843,22 +1843,25 @@ class BasicEntityPersister implements EntityPersister
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($extraConditions) {
|
||||
$criteria = array_merge($criteria, $extraConditions);
|
||||
}
|
||||
|
||||
$alias = $this->getSQLTableAlias($this->class->name);
|
||||
|
||||
$sql = 'SELECT 1 '
|
||||
. $this->getLockTablesSql(null)
|
||||
. ' WHERE ' . $this->getSelectConditionSQL($criteria);
|
||||
|
||||
list($params) = $this->expandParameters($criteria);
|
||||
|
||||
if (null !== $extraConditions) {
|
||||
$sql .= ' AND ' . $this->getSelectConditionCriteriaSQL($extraConditions);
|
||||
list($criteriaParams, $values) = $this->expandCriteriaParameters($extraConditions);
|
||||
|
||||
$params = array_merge($params, $criteriaParams);
|
||||
}
|
||||
|
||||
if ($filterSql = $this->generateFilterConditionSQL($this->class, $alias)) {
|
||||
$sql .= ' AND ' . $filterSql;
|
||||
}
|
||||
|
||||
list($params) = $this->expandParameters($criteria);
|
||||
|
||||
return (bool) $this->conn->fetchColumn($sql, $params);
|
||||
}
|
||||
|
||||
|
@ -319,10 +319,10 @@ interface EntityPersister
|
||||
/**
|
||||
* Checks whether the given managed entity exists in the database.
|
||||
*
|
||||
* @param object $entity
|
||||
* @param array $extraConditions
|
||||
* @param object $entity
|
||||
* @param Criteria|null $extraConditions
|
||||
*
|
||||
* @return boolean TRUE if the entity exists in the database, FALSE otherwise.
|
||||
*/
|
||||
public function exists($entity, array $extraConditions = array());
|
||||
public function exists($entity, Criteria $extraConditions = null);
|
||||
}
|
||||
|
@ -19,6 +19,7 @@
|
||||
|
||||
namespace Doctrine\ORM\Persisters;
|
||||
|
||||
use Doctrine\Common\Collections\Criteria;
|
||||
use Doctrine\ORM\PersistentCollection;
|
||||
use Doctrine\ORM\UnitOfWork;
|
||||
|
||||
@ -168,7 +169,7 @@ class OneToManyPersister extends AbstractCollectionPersister
|
||||
|
||||
return (bool) $this->conn->fetchColumn($sql, $params);
|
||||
}
|
||||
|
||||
|
||||
private function getJoinTableRestrictions(PersistentCollection $coll, $addFilters)
|
||||
{
|
||||
$mapping = $coll->getMapping();
|
||||
@ -227,9 +228,9 @@ class OneToManyPersister extends AbstractCollectionPersister
|
||||
// only works with single id identifier entities. Will throw an
|
||||
// exception in Entity Persisters if that is not the case for the
|
||||
// 'mappedBy' field.
|
||||
$id = current($uow->getEntityIdentifier($coll->getOwner()));
|
||||
$criteria = new Criteria(Criteria::expr()->eq($mapping['mappedBy'], $coll->getOwner()));
|
||||
|
||||
return $persister->exists($element, array($mapping['mappedBy'] => $id));
|
||||
return $persister->exists($element, $criteria);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -287,9 +287,13 @@ final class Query extends AbstractQuery
|
||||
|
||||
// Prepare parameters
|
||||
$paramMappings = $this->_parserResult->getParameterMappings();
|
||||
$paramCount = count($this->parameters);
|
||||
$mappingCount = count($paramMappings);
|
||||
|
||||
if (count($paramMappings) != count($this->parameters)) {
|
||||
throw QueryException::invalidParameterNumber();
|
||||
if ($paramCount > $mappingCount) {
|
||||
throw QueryException::tooManyParameters($mappingCount, $paramCount);
|
||||
} elseif ($paramCount < $mappingCount) {
|
||||
throw QueryException::tooFewParameters($mappingCount, $paramCount);
|
||||
}
|
||||
|
||||
// evict all cache for the entity region
|
||||
@ -682,8 +686,14 @@ final class Query extends AbstractQuery
|
||||
{
|
||||
ksort($this->_hints);
|
||||
|
||||
$platform = $this->getEntityManager()
|
||||
->getConnection()
|
||||
->getDatabasePlatform()
|
||||
->getName();
|
||||
|
||||
return md5(
|
||||
$this->getDql() . serialize($this->_hints) .
|
||||
'&platform=' . $platform .
|
||||
($this->_em->hasFilters() ? $this->_em->getFilters()->getHash() : '') .
|
||||
'&firstResult=' . $this->_firstResult . '&maxResult=' . $this->_maxResults .
|
||||
'&hydrationMode='.$this->_hydrationMode.'DOCTRINE_QUERY_CACHE_SALT'
|
||||
|
@ -93,11 +93,25 @@ class QueryException extends \Doctrine\ORM\ORMException
|
||||
}
|
||||
|
||||
/**
|
||||
* @param integer $expected
|
||||
* @param integer $received
|
||||
*
|
||||
* @return QueryException
|
||||
*/
|
||||
public static function invalidParameterNumber()
|
||||
public static function tooManyParameters($expected, $received)
|
||||
{
|
||||
return new self("Invalid parameter number: number of bound variables does not match number of tokens");
|
||||
return new self('Too many parameters: the query defines ' . $expected . ' parameters and you bound ' . $received);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param integer $expected
|
||||
* @param integer $received
|
||||
*
|
||||
* @return QueryException
|
||||
*/
|
||||
public static function tooFewParameters($expected, $received)
|
||||
{
|
||||
return new self('Too few parameters: the query defines ' . $expected . ' parameters but you only bound ' . $received);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -753,12 +753,20 @@ class SqlWalker implements TreeWalker
|
||||
$owningClass = (isset($assoc['inherited'])) ? $this->em->getClassMetadata($assoc['inherited']) : $class;
|
||||
$sqlTableAlias = $this->getSQLTableAlias($owningClass->getTableName(), $dqlAlias);
|
||||
|
||||
foreach ($assoc['targetToSourceKeyColumns'] as $srcColumn) {
|
||||
$targetClass = $this->em->getClassMetadata($assoc['targetEntity']);
|
||||
|
||||
foreach ($assoc['targetToSourceKeyColumns'] as $targetColumn => $srcColumn) {
|
||||
$columnAlias = $this->getSQLColumnAlias($srcColumn);
|
||||
|
||||
$type = null;
|
||||
$isIdentifier = (isset($assoc['id']) && $assoc['id'] === true);
|
||||
$sqlSelectExpressions[] = $sqlTableAlias . '.' . $srcColumn . ' AS ' . $columnAlias;
|
||||
|
||||
$this->rsm->addMetaResult($dqlAlias, $columnAlias, $srcColumn, (isset($assoc['id']) && $assoc['id'] === true));
|
||||
if (isset($targetClass->fieldNames[$targetColumn])) {
|
||||
$type = $targetClass->fieldMappings[$targetClass->fieldNames[$targetColumn]]['type'];
|
||||
}
|
||||
|
||||
$this->rsm->addMetaResult($dqlAlias, $columnAlias, $srcColumn, $isIdentifier, $type);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1968,7 +1976,7 @@ class SqlWalker implements TreeWalker
|
||||
$this->parserResult->addParameterMapping($dqlParamKey, $this->sqlParamIndex++);
|
||||
}
|
||||
|
||||
$sqlParts[] = $targetTableAlias . '.' . $targetColumnName . ' = ' . $entitySql;
|
||||
$sqlParts[] = $targetTableAlias . '.' . $targetColumnName . ' IN (' . $entitySql . ')';
|
||||
}
|
||||
|
||||
$sql .= implode(' AND ', $sqlParts);
|
||||
|
@ -134,7 +134,7 @@ class EntityGenerator
|
||||
|
||||
/**
|
||||
* Visibility of the field
|
||||
*
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $fieldVisibility = 'private';
|
||||
@ -570,7 +570,7 @@ public function __construct()
|
||||
return 'namespace ' . $this->getNamespace($metadata) .';';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected function generateEntityUse()
|
||||
{
|
||||
if ($this->generateAnnotations) {
|
||||
@ -696,9 +696,9 @@ public function __construct()
|
||||
$inClass = true;
|
||||
} elseif ($token[0] == T_FUNCTION) {
|
||||
if ($tokens[$i+2][0] == T_STRING) {
|
||||
$this->staticReflection[$lastSeenClass]['methods'][] = $tokens[$i+2][1];
|
||||
$this->staticReflection[$lastSeenClass]['methods'][] = strtolower($tokens[$i+2][1]);
|
||||
} elseif ($tokens[$i+2] == "&" && $tokens[$i+3][0] == T_STRING) {
|
||||
$this->staticReflection[$lastSeenClass]['methods'][] = $tokens[$i+3][1];
|
||||
$this->staticReflection[$lastSeenClass]['methods'][] = strtolower($tokens[$i+3][1]);
|
||||
}
|
||||
} elseif (in_array($token[0], array(T_VAR, T_PUBLIC, T_PRIVATE, T_PROTECTED)) && $tokens[$i+2][0] != T_FUNCTION) {
|
||||
$this->staticReflection[$lastSeenClass]['properties'][] = substr($tokens[$i+2][1], 1);
|
||||
@ -761,7 +761,7 @@ public function __construct()
|
||||
|
||||
return (
|
||||
isset($this->staticReflection[$metadata->name]) &&
|
||||
in_array($method, $this->staticReflection[$metadata->name]['methods'])
|
||||
in_array(strtolower($method), $this->staticReflection[$metadata->name]['methods'])
|
||||
);
|
||||
}
|
||||
|
||||
@ -1149,14 +1149,16 @@ public function __construct()
|
||||
protected function generateEntityStubMethod(ClassMetadataInfo $metadata, $type, $fieldName, $typeHint = null, $defaultValue = null)
|
||||
{
|
||||
$methodName = $type . Inflector::classify($fieldName);
|
||||
$variableName = Inflector::camelize($fieldName);
|
||||
if (in_array($type, array("add", "remove"))) {
|
||||
$methodName = Inflector::singularize($methodName);
|
||||
$variableName = Inflector::singularize($variableName);
|
||||
}
|
||||
|
||||
if ($this->hasMethod($methodName, $metadata)) {
|
||||
return '';
|
||||
}
|
||||
$this->staticReflection[$metadata->name]['methods'][] = $methodName;
|
||||
$this->staticReflection[$metadata->name]['methods'][] = strtolower($methodName);
|
||||
|
||||
$var = sprintf('%sMethodTemplate', $type);
|
||||
$template = static::$$var;
|
||||
@ -1171,10 +1173,10 @@ public function __construct()
|
||||
}
|
||||
|
||||
$replacements = array(
|
||||
'<description>' => ucfirst($type) . ' ' . $fieldName,
|
||||
'<description>' => ucfirst($type) . ' ' . $variableName . ".\n",
|
||||
'<methodTypeHint>' => $methodTypeHint,
|
||||
'<variableType>' => $variableType,
|
||||
'<variableName>' => Inflector::camelize($fieldName),
|
||||
'<variableName>' => $variableName,
|
||||
'<methodName>' => $methodName,
|
||||
'<fieldName>' => $fieldName,
|
||||
'<variableDefault>' => ($defaultValue !== null ) ? (' = '.$defaultValue) : '',
|
||||
@ -1445,11 +1447,11 @@ public function __construct()
|
||||
if (isset($fieldMapping['nullable'])) {
|
||||
$column[] = 'nullable=' . var_export($fieldMapping['nullable'], true);
|
||||
}
|
||||
|
||||
|
||||
if (isset($fieldMapping['unsigned']) && $fieldMapping['unsigned']) {
|
||||
$column[] = 'options={"unsigned"=true}';
|
||||
}
|
||||
|
||||
|
||||
if (isset($fieldMapping['columnDefinition'])) {
|
||||
$column[] = 'columnDefinition="' . $fieldMapping['columnDefinition'] . '"';
|
||||
}
|
||||
@ -1571,15 +1573,15 @@ public function __construct()
|
||||
private function exportTableOptions(array $options)
|
||||
{
|
||||
$optionsStr = array();
|
||||
|
||||
|
||||
foreach($options as $name => $option) {
|
||||
if (is_array($option)) {
|
||||
$optionsStr[] = '"' . $name . '"={' . $this->exportTableOptions($option) . '}';
|
||||
} else {
|
||||
$optionsStr[] = '"' . $name . '"="' . (string) $option . '"';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return implode(',', $optionsStr);
|
||||
}
|
||||
}
|
||||
|
@ -21,6 +21,7 @@ namespace Doctrine\ORM\Tools;
|
||||
|
||||
use Doctrine\Common\ClassLoader;
|
||||
use Doctrine\Common\Cache\Cache;
|
||||
use Doctrine\Common\Cache\CacheProvider;
|
||||
use Doctrine\Common\Cache\ArrayCache;
|
||||
use Doctrine\ORM\Configuration;
|
||||
use Doctrine\ORM\Mapping\Driver\XmlDriver;
|
||||
@ -144,7 +145,9 @@ class Setup
|
||||
$cache = new ArrayCache();
|
||||
}
|
||||
|
||||
$cache->setNamespace("dc2_" . md5($proxyDir) . "_"); // to avoid collisions
|
||||
if ($cache instanceof CacheProvider) {
|
||||
$cache->setNamespace("dc2_" . md5($proxyDir) . "_"); // to avoid collisions
|
||||
}
|
||||
|
||||
$config = new Configuration();
|
||||
$config->setMetadataCacheImpl($cache);
|
||||
|
@ -943,12 +943,13 @@ class UnitOfWork implements PropertyChangedListener
|
||||
}
|
||||
|
||||
if ($changeSet) {
|
||||
$this->entityChangeSets[$oid] = (isset($this->entityChangeSets[$oid]))
|
||||
? array_merge($this->entityChangeSets[$oid], $changeSet)
|
||||
: $changeSet;
|
||||
|
||||
if (isset($this->entityChangeSets[$oid])) {
|
||||
$this->entityChangeSets[$oid] = array_merge($this->entityChangeSets[$oid], $changeSet);
|
||||
} else if ( ! isset($this->entityInsertions[$oid])) {
|
||||
$this->entityChangeSets[$oid] = $changeSet;
|
||||
$this->entityUpdates[$oid] = $entity;
|
||||
}
|
||||
$this->originalEntityData[$oid] = $actualData;
|
||||
$this->entityUpdates[$oid] = $entity;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2405,12 +2406,12 @@ class UnitOfWork implements PropertyChangedListener
|
||||
}
|
||||
} else {
|
||||
$visited = array();
|
||||
|
||||
|
||||
foreach ($this->identityMap as $className => $entities) {
|
||||
if ($className !== $entityName) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
foreach ($entities as $entity) {
|
||||
$this->doDetach($entity, $visited, false);
|
||||
}
|
||||
@ -2522,7 +2523,7 @@ class UnitOfWork implements PropertyChangedListener
|
||||
|
||||
$id = array($class->identifier[0] => $id);
|
||||
}
|
||||
|
||||
|
||||
$idHash = implode(' ', $id);
|
||||
|
||||
if (isset($this->identityMap[$class->rootEntityName][$idHash])) {
|
||||
|
@ -86,13 +86,13 @@ class EntityManagerMock extends \Doctrine\ORM\EntityManager
|
||||
public static function create($conn, \Doctrine\ORM\Configuration $config = null,
|
||||
\Doctrine\Common\EventManager $eventManager = null)
|
||||
{
|
||||
if (is_null($config)) {
|
||||
if (null === $config) {
|
||||
$config = new \Doctrine\ORM\Configuration();
|
||||
$config->setProxyDir(__DIR__ . '/../Proxies');
|
||||
$config->setProxyNamespace('Doctrine\Tests\Proxies');
|
||||
$config->setMetadataDriverImpl($config->newDefaultAnnotationDriver(array(), true));
|
||||
}
|
||||
if (is_null($eventManager)) {
|
||||
if (null === $eventManager) {
|
||||
$eventManager = new \Doctrine\Common\EventManager();
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\Mocks;
|
||||
use Doctrine\Common\Collections\Criteria;
|
||||
|
||||
/**
|
||||
* EntityPersister implementation used for mocking during tests.
|
||||
@ -88,7 +89,7 @@ class EntityPersisterMock extends \Doctrine\ORM\Persisters\BasicEntityPersister
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function exists($entity, array $extraConditions = array())
|
||||
public function exists($entity, Criteria $extraConditions = null)
|
||||
{
|
||||
$this->existsCalled = true;
|
||||
}
|
||||
|
@ -433,8 +433,8 @@ abstract class AbstractEntityPersisterTest extends OrmTestCase
|
||||
|
||||
$this->entityPersister->expects($this->once())
|
||||
->method('exists')
|
||||
->with($this->equalTo($entity), $this->equalTo(array()));
|
||||
->with($this->equalTo($entity), $this->equalTo(null));
|
||||
|
||||
$this->assertNull($persister->exists($entity, array()));
|
||||
$this->assertNull($persister->exists($entity));
|
||||
}
|
||||
}
|
||||
|
@ -21,6 +21,8 @@ namespace Doctrine\Tests\ORM\Functional;
|
||||
|
||||
use Doctrine\Tests\Models\Generic\DateTimeModel;
|
||||
use Doctrine\Common\Collections\Criteria;
|
||||
use Doctrine\Tests\Models\Tweet\Tweet;
|
||||
use Doctrine\Tests\Models\Tweet\User;
|
||||
|
||||
/**
|
||||
* @author Josiah <josiah@jjs.id.au>
|
||||
@ -30,6 +32,7 @@ class EntityRepositoryCriteriaTest extends \Doctrine\Tests\OrmFunctionalTestCase
|
||||
protected function setUp()
|
||||
{
|
||||
$this->useModelSet('generic');
|
||||
$this->useModelSet('tweet');
|
||||
parent::setUp();
|
||||
}
|
||||
|
||||
@ -165,4 +168,34 @@ class EntityRepositoryCriteriaTest extends \Doctrine\Tests\OrmFunctionalTestCase
|
||||
$date = $dates[0];
|
||||
$this->assertTrue($dates->isInitialized());
|
||||
}
|
||||
|
||||
public function testCanContainsWithoutLoadingCollection()
|
||||
{
|
||||
$user = new User();
|
||||
$user->name = 'Marco';
|
||||
$this->_em->persist($user);
|
||||
$this->_em->flush();
|
||||
|
||||
$tweet = new Tweet();
|
||||
$tweet->author = $user;
|
||||
$tweet->content = 'Criteria is awesome';
|
||||
$this->_em->persist($tweet);
|
||||
$this->_em->flush();
|
||||
|
||||
$this->_em->clear();
|
||||
|
||||
$criteria = new Criteria();
|
||||
$criteria->andWhere($criteria->expr()->contains('content', 'Criteria'));
|
||||
|
||||
$user = $this->_em->find('Doctrine\Tests\Models\Tweet\User', $user->id);
|
||||
$tweets = $user->tweets->matching($criteria);
|
||||
|
||||
$this->assertInstanceOf('Doctrine\ORM\LazyCriteriaCollection', $tweets);
|
||||
$this->assertFalse($tweets->isInitialized());
|
||||
|
||||
$tweets->contains($tweet);
|
||||
$this->assertTrue($tweets->contains($tweet));
|
||||
|
||||
$this->assertFalse($tweets->isInitialized());
|
||||
}
|
||||
}
|
||||
|
@ -127,11 +127,11 @@ class QueryTest extends \Doctrine\Tests\OrmFunctionalTestCase
|
||||
$user = $q->getSingleResult();
|
||||
}
|
||||
|
||||
public function testMismatchingParamExpectedParamCount()
|
||||
public function testTooManyParametersShouldThrowException()
|
||||
{
|
||||
$this->setExpectedException(
|
||||
"Doctrine\ORM\Query\QueryException",
|
||||
"Invalid parameter number: number of bound variables does not match number of tokens"
|
||||
"Too many parameters: the query defines 1 parameters and you bound 2"
|
||||
);
|
||||
|
||||
$q = $this->_em->createQuery('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.name = ?1');
|
||||
@ -141,6 +141,18 @@ class QueryTest extends \Doctrine\Tests\OrmFunctionalTestCase
|
||||
$user = $q->getSingleResult();
|
||||
}
|
||||
|
||||
public function testTooFewParametersShouldThrowException()
|
||||
{
|
||||
$this->setExpectedException(
|
||||
"Doctrine\ORM\Query\QueryException",
|
||||
"Too few parameters: the query defines 1 parameters but you only bound 0"
|
||||
);
|
||||
|
||||
$q = $this->_em->createQuery('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.name = ?1');
|
||||
|
||||
$user = $q->getSingleResult();
|
||||
}
|
||||
|
||||
public function testInvalidInputParameterThrowsException()
|
||||
{
|
||||
$this->setExpectedException("Doctrine\ORM\Query\QueryException");
|
||||
|
70
tests/Doctrine/Tests/ORM/Functional/Ticket/DDC3160Test.php
Normal file
70
tests/Doctrine/Tests/ORM/Functional/Ticket/DDC3160Test.php
Normal file
@ -0,0 +1,70 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\ORM\Functional\Ticket;
|
||||
|
||||
use Doctrine\Tests\Models\CMS\CmsUser;
|
||||
use Doctrine\ORM\Event\OnFlushEventArgs;
|
||||
use Doctrine\ORM\Events;
|
||||
use Doctrine\Tests\OrmFunctionalTestCase;
|
||||
|
||||
/**
|
||||
* FlushEventTest
|
||||
*
|
||||
* @author robo
|
||||
*/
|
||||
class DDC3160Test extends OrmFunctionalTestCase
|
||||
{
|
||||
protected function setUp() {
|
||||
$this->useModelSet('cms');
|
||||
parent::setUp();
|
||||
}
|
||||
|
||||
/**
|
||||
* @group DDC-3160
|
||||
*/
|
||||
public function testNoUpdateOnInsert()
|
||||
{
|
||||
$listener = new DDC3160OnFlushListener();
|
||||
$this->_em->getEventManager()->addEventListener(Events::onFlush, $listener);
|
||||
|
||||
$user = new CmsUser;
|
||||
$user->username = 'romanb';
|
||||
$user->name = 'Roman';
|
||||
$user->status = 'Dev';
|
||||
|
||||
$this->_em->persist($user);
|
||||
$this->_em->flush();
|
||||
|
||||
$this->_em->refresh($user);
|
||||
|
||||
$this->assertEquals('romanc', $user->username);
|
||||
$this->assertEquals(1, $listener->inserts);
|
||||
$this->assertEquals(0, $listener->updates);
|
||||
}
|
||||
}
|
||||
|
||||
class DDC3160OnFlushListener
|
||||
{
|
||||
public $inserts = 0;
|
||||
public $updates = 0;
|
||||
|
||||
public function onFlush(OnFlushEventArgs $args)
|
||||
{
|
||||
$em = $args->getEntityManager();
|
||||
$uow = $em->getUnitOfWork();
|
||||
|
||||
foreach ($uow->getScheduledEntityInsertions() as $entity) {
|
||||
$this->inserts++;
|
||||
if ($entity instanceof CmsUser) {
|
||||
$entity->username = 'romanc';
|
||||
$cm = $em->getClassMetadata(get_class($entity));
|
||||
$uow->recomputeSingleEntityChangeSet($cm, $entity);
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($uow->getScheduledEntityUpdates() as $entity) {
|
||||
$this->updates++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
110
tests/Doctrine/Tests/ORM/Functional/Ticket/DDC3170Test.php
Normal file
110
tests/Doctrine/Tests/ORM/Functional/Ticket/DDC3170Test.php
Normal file
@ -0,0 +1,110 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\ORM\Functional\Ticket;
|
||||
|
||||
use Doctrine\ORM\AbstractQuery;
|
||||
use Doctrine\ORM\Internal\Hydration\HydrationException;
|
||||
|
||||
/**
|
||||
* @group DDC-2306
|
||||
*/
|
||||
class DDC3170Test extends \Doctrine\Tests\OrmFunctionalTestCase
|
||||
{
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
protected function setup()
|
||||
{
|
||||
parent::setup();
|
||||
|
||||
$this->_schemaTool->createSchema(
|
||||
array(
|
||||
$this->_em->getClassMetadata(__NAMESPACE__ . '\DDC3170AbstractEntityJoined'),
|
||||
$this->_em->getClassMetadata(__NAMESPACE__ . '\DDC3170ProductJoined'),
|
||||
$this->_em->getClassMetadata(__NAMESPACE__ . '\DDC3170AbstractEntitySingleTable'),
|
||||
$this->_em->getClassMetadata(__NAMESPACE__ . '\DDC3170ProductSingleTable'),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that the discriminator column is correctly read from the meta mappings when fetching a
|
||||
* child from an inheritance mapped class.
|
||||
*
|
||||
* The simple object hydration maps the type field to a field alias like type2. This mapping needs
|
||||
* to be considered when loading the discriminator column's value from the SQL result.
|
||||
*
|
||||
* {@see \Doctrine\ORM\Internal\Hydration\SimpleObjectHydrator::hydrateRowData()}
|
||||
*/
|
||||
public function testIssue()
|
||||
{
|
||||
// $this->_em->getConnection()->getConfiguration()->setSQLLogger(new \Doctrine\DBAL\Logging\EchoSQLLogger);
|
||||
|
||||
$productJoined = new DDC3170ProductJoined();
|
||||
$productSingleTable = new DDC3170ProductSingleTable();
|
||||
$this->_em->persist($productJoined);
|
||||
$this->_em->persist($productSingleTable);
|
||||
$this->_em->flush();
|
||||
$this->_em->clear();
|
||||
|
||||
try {
|
||||
$this->_em->createQueryBuilder()
|
||||
->select('p')
|
||||
->from(__NAMESPACE__ . '\\DDC3170ProductJoined', 'p')
|
||||
->getQuery()
|
||||
->getResult(AbstractQuery::HYDRATE_SIMPLEOBJECT);
|
||||
} catch (HydrationException $e) // Thrown by SimpleObjectHydrator
|
||||
{
|
||||
$this->fail('Failed correct mapping of discriminator column when using simple object hydration and class table inheritance');
|
||||
}
|
||||
|
||||
try {
|
||||
$this->_em->createQueryBuilder()
|
||||
->select('p')
|
||||
->from(__NAMESPACE__ . '\\DDC3170ProductSingleTable', 'p')
|
||||
->getQuery()
|
||||
->getResult(AbstractQuery::HYDRATE_SIMPLEOBJECT);
|
||||
} catch (HydrationException $e) // Thrown by SimpleObjectHydrator
|
||||
{
|
||||
$this->fail('Failed correct mapping of discriminator column when using simple object hydration and single table inheritance');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @Entity
|
||||
* @InheritanceType("JOINED")
|
||||
* @DiscriminatorColumn(name="type", type="string")
|
||||
* @DiscriminatorMap({"product" = "DDC3170ProductJoined"})
|
||||
*/
|
||||
abstract class DDC3170AbstractEntityJoined
|
||||
{
|
||||
/** @Id @Column(type="integer") @GeneratedValue */
|
||||
public $id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @Entity
|
||||
*/
|
||||
class DDC3170ProductJoined extends DDC3170AbstractEntityJoined
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @Entity
|
||||
* @InheritanceType("SINGLE_TABLE")
|
||||
* @DiscriminatorColumn(name="type", type="string")
|
||||
* @DiscriminatorMap({"product" = "DDC3170ProductSingleTable"})
|
||||
*/
|
||||
abstract class DDC3170AbstractEntitySingleTable
|
||||
{
|
||||
/** @Id @Column(type="integer") @GeneratedValue */
|
||||
public $id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @Entity
|
||||
*/
|
||||
class DDC3170ProductSingleTable extends DDC3170AbstractEntitySingleTable
|
||||
{
|
||||
}
|
168
tests/Doctrine/Tests/ORM/Functional/Ticket/DDC3192Test.php
Normal file
168
tests/Doctrine/Tests/ORM/Functional/Ticket/DDC3192Test.php
Normal file
@ -0,0 +1,168 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\ORM\Functional\Ticket;
|
||||
|
||||
use Doctrine\DBAL\Types\Type;
|
||||
use Doctrine\DBAL\Platforms\AbstractPlatform;
|
||||
use Doctrine\ORM\Query;
|
||||
|
||||
/**
|
||||
* @group DDC-2494
|
||||
* @group non-cacheable
|
||||
*/
|
||||
class DDC3192Test extends \Doctrine\Tests\OrmFunctionalTestCase
|
||||
{
|
||||
protected function setUp()
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
if (Type::hasType('ddc3192_currency_code')) {
|
||||
$this->fail(
|
||||
'Type ddc3192_currency_code exists for testing DDC-3192 only, ' .
|
||||
'but it has already been registered for some reason'
|
||||
);
|
||||
}
|
||||
|
||||
Type::addType('ddc3192_currency_code', __NAMESPACE__ . '\DDC3192CurrencyCode');
|
||||
|
||||
$this->_schemaTool->createSchema(array(
|
||||
$this->_em->getClassMetadata(DDC3192Currency::CLASSNAME),
|
||||
$this->_em->getClassMetadata(DDC3192Transaction::CLASSNAME),
|
||||
));
|
||||
}
|
||||
|
||||
public function testIssue()
|
||||
{
|
||||
$currency = new DDC3192Currency('BYR');
|
||||
|
||||
$this->_em->persist($currency);
|
||||
$this->_em->flush();
|
||||
|
||||
$amount = 50;
|
||||
$transaction = new DDC3192Transaction($amount, $currency);
|
||||
|
||||
$this->_em->persist($transaction);
|
||||
$this->_em->flush();
|
||||
$this->_em->close();
|
||||
|
||||
$resultByPersister = $this->_em->find(DDC3192Transaction::CLASSNAME, $transaction->id);
|
||||
|
||||
// This works: DDC2494 makes persister set type mapping info to ResultSetMapping
|
||||
$this->assertEquals('BYR', $resultByPersister->currency->code);
|
||||
|
||||
$this->_em->close();
|
||||
|
||||
$query = $this->_em->createQuery();
|
||||
$query->setDQL('SELECT t FROM ' . DDC3192Transaction::CLASSNAME . ' t WHERE t.id = ?1');
|
||||
$query->setParameter(1, $transaction->id);
|
||||
|
||||
$resultByQuery = $query->getSingleResult();
|
||||
|
||||
// This is fixed here: before the fix it used to return 974.
|
||||
// because unlike the BasicEntityPersister, SQLWalker doesn't set type info
|
||||
$this->assertEquals('BYR', $resultByQuery->currency->code);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @Table(name="ddc3192_currency")
|
||||
* @Entity
|
||||
*/
|
||||
class DDC3192Currency
|
||||
{
|
||||
const CLASSNAME = __CLASS__;
|
||||
|
||||
/**
|
||||
* @Id
|
||||
* @Column(type="ddc3192_currency_code")
|
||||
*/
|
||||
public $code;
|
||||
|
||||
/**
|
||||
* @var \Doctrine\Common\Collections\Collection
|
||||
*
|
||||
* @OneToMany(targetEntity="DDC3192Transaction", mappedBy="currency")
|
||||
*/
|
||||
public $transactions;
|
||||
|
||||
public function __construct($code)
|
||||
{
|
||||
$this->code = $code;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @Table(name="ddc3192_transaction")
|
||||
* @Entity
|
||||
*/
|
||||
class DDC3192Transaction
|
||||
{
|
||||
const CLASSNAME = __CLASS__;
|
||||
|
||||
/**
|
||||
* @Id
|
||||
* @GeneratedValue
|
||||
* @Column(type="integer")
|
||||
*/
|
||||
public $id;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*
|
||||
* @Column(type="integer")
|
||||
*/
|
||||
public $amount;
|
||||
|
||||
/**
|
||||
* @var \Doctrine\Tests\ORM\Functional\Ticket\DDC3192Currency
|
||||
*
|
||||
* @ManyToOne(targetEntity="DDC3192Currency", inversedBy="transactions")
|
||||
* @JoinColumn(name="currency_id", referencedColumnName="code", nullable=false)
|
||||
*/
|
||||
public $currency;
|
||||
|
||||
public function __construct($amount, DDC3192Currency $currency)
|
||||
{
|
||||
$this->amount = $amount;
|
||||
$this->currency = $currency;
|
||||
}
|
||||
}
|
||||
|
||||
class DDC3192CurrencyCode extends Type
|
||||
{
|
||||
private static $map = array(
|
||||
'BYR' => 974,
|
||||
);
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $platform)
|
||||
{
|
||||
return $platform->getSmallIntTypeDeclarationSQL($fieldDeclaration);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function convertToDatabaseValue($value, AbstractPlatform $platform)
|
||||
{
|
||||
return self::$map[$value];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function convertToPHPValue($value, AbstractPlatform $platform)
|
||||
{
|
||||
return array_search($value, self::$map);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return 'ddc3192_currency_code';
|
||||
}
|
||||
}
|
@ -160,7 +160,7 @@ class AnnotationDriverTest extends AbstractMappingDriverTest
|
||||
$factory->setEntityManager($em);
|
||||
|
||||
$this->setExpectedException('Doctrine\ORM\Mapping\MappingException',
|
||||
"Its not supported to define inheritance information on a mapped ".
|
||||
"It is not supported to define inheritance information on a mapped ".
|
||||
"superclass 'Doctrine\Tests\ORM\Mapping\MappedSuperClassInheritence'.");
|
||||
$usingInvalidMsc = $factory->getMetadataFor('Doctrine\Tests\ORM\Mapping\MappedSuperClassInheritence');
|
||||
}
|
||||
|
@ -2,10 +2,9 @@
|
||||
|
||||
namespace Doctrine\Tests\ORM\Mapping;
|
||||
|
||||
use Doctrine\ORM\Mapping\ClassMetadata,
|
||||
Doctrine\ORM\Mapping\ClassMetadataFactory,
|
||||
Doctrine\ORM\Mapping\Driver\XmlDriver,
|
||||
Doctrine\ORM\Mapping\Driver\YamlDriver;
|
||||
use Doctrine\ORM\Mapping\ClassMetadata;
|
||||
use Doctrine\ORM\Mapping\ClassMetadataFactory;
|
||||
use Doctrine\ORM\Mapping\Driver\XmlDriver;
|
||||
|
||||
class XmlMappingDriverTest extends AbstractMappingDriverTest
|
||||
{
|
||||
@ -24,9 +23,9 @@ class XmlMappingDriverTest extends AbstractMappingDriverTest
|
||||
$mappingDriver->loadMetadataForClass($className, $class);
|
||||
|
||||
$expectedMap = array(
|
||||
"foo" => "Doctrine\Tests\ORM\Mapping\CTIFoo",
|
||||
"bar" => "Doctrine\Tests\ORM\Mapping\CTIBar",
|
||||
"baz" => "Doctrine\Tests\ORM\Mapping\CTIBaz",
|
||||
'foo' => 'Doctrine\Tests\ORM\Mapping\CTIFoo',
|
||||
'bar' => 'Doctrine\Tests\ORM\Mapping\CTIBar',
|
||||
'baz' => 'Doctrine\Tests\ORM\Mapping\CTIBaz',
|
||||
);
|
||||
|
||||
$this->assertEquals(3, count($class->discriminatorMap));
|
||||
@ -117,7 +116,7 @@ class XmlMappingDriverTest extends AbstractMappingDriverTest
|
||||
|
||||
/**
|
||||
* @group DDC-889
|
||||
* @expectedException Doctrine\Common\Persistence\Mapping\MappingException
|
||||
* @expectedException \Doctrine\Common\Persistence\Mapping\MappingException
|
||||
* @expectedExceptionMessage Invalid mapping file 'Doctrine.Tests.Models.DDC889.DDC889Class.dcm.xml' for class 'Doctrine\Tests\Models\DDC889\DDC889Class'.
|
||||
*/
|
||||
public function testinvalidEntityOrMappedSuperClassShouldMentionParentClasses()
|
||||
|
@ -54,7 +54,7 @@
|
||||
|
||||
<one-to-one field="address" target-entity="Address" inversed-by="user">
|
||||
<cascade><cascade-remove /></cascade>
|
||||
<join-column name="address_id" referenced-column-name="id" on-delete="CASCADE" on-update="CASCADE"/>
|
||||
<join-column name="address_id" referenced-column-name="id" on-delete="CASCADE" />
|
||||
</one-to-one>
|
||||
|
||||
<one-to-many field="phonenumbers" target-entity="Phonenumber" mapped-by="user" index-by="number" orphan-removal="true">
|
||||
|
@ -623,7 +623,24 @@ class SelectSqlGenerationTest extends \Doctrine\Tests\OrmTestCase
|
||||
$q->setParameter('param', $group);
|
||||
|
||||
$this->assertEquals(
|
||||
'SELECT c0_.id AS id_0 FROM cms_users c0_ WHERE EXISTS (SELECT 1 FROM cms_users_groups c1_ INNER JOIN cms_groups c2_ ON c1_.group_id = c2_.id WHERE c1_.user_id = c0_.id AND c2_.id = ?)',
|
||||
'SELECT c0_.id AS id_0 FROM cms_users c0_ WHERE EXISTS (SELECT 1 FROM cms_users_groups c1_ INNER JOIN cms_groups c2_ ON c1_.group_id = c2_.id WHERE c1_.user_id = c0_.id AND c2_.id IN (?))',
|
||||
$q->getSql()
|
||||
);
|
||||
}
|
||||
|
||||
public function testSupportsMemberOfExpressionManyToManyParameterArray()
|
||||
{
|
||||
$q = $this->_em->createQuery('SELECT u.id FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE :param MEMBER OF u.groups');
|
||||
$q->setHint(Query::HINT_FORCE_PARTIAL_LOAD, true);
|
||||
|
||||
$group = new \Doctrine\Tests\Models\CMS\CmsGroup;
|
||||
$group->id = 101;
|
||||
$group2 = new \Doctrine\Tests\Models\CMS\CmsGroup;
|
||||
$group2->id = 105;
|
||||
$q->setParameter('param', array($group, $group2));
|
||||
|
||||
$this->assertEquals(
|
||||
'SELECT c0_.id AS id_0 FROM cms_users c0_ WHERE EXISTS (SELECT 1 FROM cms_users_groups c1_ INNER JOIN cms_groups c2_ ON c1_.group_id = c2_.id WHERE c1_.user_id = c0_.id AND c2_.id IN (?))',
|
||||
$q->getSql()
|
||||
);
|
||||
}
|
||||
@ -637,7 +654,7 @@ class SelectSqlGenerationTest extends \Doctrine\Tests\OrmTestCase
|
||||
$this->_em->getClassMetadata(get_class($person))->setIdentifierValues($person, array('id' => 101));
|
||||
$q->setParameter('param', $person);
|
||||
$this->assertEquals(
|
||||
'SELECT c0_.id AS id_0, c0_.name AS name_1, c1_.title AS title_2, c2_.salary AS salary_3, c2_.department AS department_4, c2_.startDate AS startDate_5, c0_.discr AS discr_6, c0_.spouse_id AS spouse_id_7, c1_.car_id AS car_id_8 FROM company_persons c0_ LEFT JOIN company_managers c1_ ON c0_.id = c1_.id LEFT JOIN company_employees c2_ ON c0_.id = c2_.id WHERE EXISTS (SELECT 1 FROM company_persons_friends c3_ INNER JOIN company_persons c4_ ON c3_.friend_id = c4_.id WHERE c3_.person_id = c0_.id AND c4_.id = ?)',
|
||||
'SELECT c0_.id AS id_0, c0_.name AS name_1, c1_.title AS title_2, c2_.salary AS salary_3, c2_.department AS department_4, c2_.startDate AS startDate_5, c0_.discr AS discr_6, c0_.spouse_id AS spouse_id_7, c1_.car_id AS car_id_8 FROM company_persons c0_ LEFT JOIN company_managers c1_ ON c0_.id = c1_.id LEFT JOIN company_employees c2_ ON c0_.id = c2_.id WHERE EXISTS (SELECT 1 FROM company_persons_friends c3_ INNER JOIN company_persons c4_ ON c3_.friend_id = c4_.id WHERE c3_.person_id = c0_.id AND c4_.id IN (?))',
|
||||
$q->getSql()
|
||||
);
|
||||
}
|
||||
@ -648,7 +665,7 @@ class SelectSqlGenerationTest extends \Doctrine\Tests\OrmTestCase
|
||||
$q = $this->_em->createQuery('SELECT u.id FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.email MEMBER OF u.groups');
|
||||
|
||||
$this->assertEquals(
|
||||
'SELECT c0_.id AS id_0 FROM cms_users c0_ WHERE EXISTS (SELECT 1 FROM cms_users_groups c1_ INNER JOIN cms_groups c2_ ON c1_.group_id = c2_.id WHERE c1_.user_id = c0_.id AND c2_.id = c0_.email_id)',
|
||||
'SELECT c0_.id AS id_0 FROM cms_users c0_ WHERE EXISTS (SELECT 1 FROM cms_users_groups c1_ INNER JOIN cms_groups c2_ ON c1_.group_id = c2_.id WHERE c1_.user_id = c0_.id AND c2_.id IN (c0_.email_id))',
|
||||
$q->getSql()
|
||||
);
|
||||
}
|
||||
@ -659,7 +676,7 @@ class SelectSqlGenerationTest extends \Doctrine\Tests\OrmTestCase
|
||||
$q = $this->_em->createQuery('SELECT u.id FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u MEMBER OF u.groups');
|
||||
|
||||
$this->assertEquals(
|
||||
'SELECT c0_.id AS id_0 FROM cms_users c0_ WHERE EXISTS (SELECT 1 FROM cms_users_groups c1_ INNER JOIN cms_groups c2_ ON c1_.group_id = c2_.id WHERE c1_.user_id = c0_.id AND c2_.id = c0_.id)',
|
||||
'SELECT c0_.id AS id_0 FROM cms_users c0_ WHERE EXISTS (SELECT 1 FROM cms_users_groups c1_ INNER JOIN cms_groups c2_ ON c1_.group_id = c2_.id WHERE c1_.user_id = c0_.id AND c2_.id IN (c0_.id))',
|
||||
$q->getSql()
|
||||
);
|
||||
}
|
||||
|
@ -133,6 +133,14 @@ class EntityGeneratorTest extends \Doctrine\Tests\OrmTestCase
|
||||
$book->setName('Jonathan H. Wage');
|
||||
$this->assertEquals('Jonathan H. Wage', $book->getName());
|
||||
|
||||
$reflMethod = new \ReflectionMethod($metadata->name, 'addComment');
|
||||
$addCommentParameters = $reflMethod->getParameters();
|
||||
$this->assertEquals('comment', $addCommentParameters[0]->getName());
|
||||
|
||||
$reflMethod = new \ReflectionMethod($metadata->name, 'removeComment');
|
||||
$removeCommentParameters = $reflMethod->getParameters();
|
||||
$this->assertEquals('comment', $removeCommentParameters[0]->getName());
|
||||
|
||||
$author = new EntityGeneratorAuthor();
|
||||
$book->setAuthor($author);
|
||||
$this->assertEquals($author, $book->getAuthor());
|
||||
@ -169,6 +177,30 @@ class EntityGeneratorTest extends \Doctrine\Tests\OrmTestCase
|
||||
$this->assertTrue($reflClass->getMethod('getTest')->isPublic(), "Check for public visibility of method 'getTest' failed.");
|
||||
}
|
||||
|
||||
/**
|
||||
* @group DDC-3152
|
||||
*/
|
||||
public function testDoesNotRegenerateExistingMethodsWithDifferentCase()
|
||||
{
|
||||
$metadata = $this->generateBookEntityFixture();
|
||||
|
||||
// Workaround to change existing fields case (just to simulate the use case)
|
||||
$metadata->fieldMappings['status']['fieldName'] = 'STATUS';
|
||||
|
||||
// Should not throw a PHP fatal error
|
||||
$this->_generator->writeEntityClass($metadata, $this->_tmpDir);
|
||||
|
||||
$this->assertFileExists($this->_tmpDir . "/" . $this->_namespace . "/EntityGeneratorBook.php~");
|
||||
|
||||
$this->newInstance($metadata);
|
||||
$reflClass = new \ReflectionClass($metadata->name);
|
||||
|
||||
$this->assertTrue($reflClass->hasProperty('status'));
|
||||
$this->assertTrue($reflClass->hasProperty('STATUS'));
|
||||
$this->assertTrue($reflClass->hasMethod('getStatus'));
|
||||
$this->assertTrue($reflClass->hasMethod('setStatus'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @group DDC-2121
|
||||
*/
|
||||
|
@ -89,4 +89,19 @@ class SetupTest extends \Doctrine\Tests\OrmTestCase
|
||||
$this->assertSame($cache, $config->getMetadataCacheImpl());
|
||||
$this->assertSame($cache, $config->getQueryCacheImpl());
|
||||
}
|
||||
|
||||
/**
|
||||
* @group DDC-3190
|
||||
*/
|
||||
public function testConfigureCacheCustomInstance()
|
||||
{
|
||||
$cache = $this->getMock('Doctrine\Common\Cache\Cache');
|
||||
$cache->expects($this->never())->method('setNamespace');
|
||||
|
||||
$config = Setup::createConfiguration(array(), true, $cache);
|
||||
|
||||
$this->assertSame($cache, $config->getResultCacheImpl());
|
||||
$this->assertSame($cache, $config->getMetadataCacheImpl());
|
||||
$this->assertSame($cache, $config->getQueryCacheImpl());
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user