Merge branch 'master' of github.com:doctrine/doctrine2
This commit is contained in:
commit
b8b5c2d686
@ -1,4 +0,0 @@
|
|||||||
# for php-coveralls
|
|
||||||
service_name: travis-ci
|
|
||||||
src_dir: lib
|
|
||||||
coverage_clover: build/logs/clover*.xml
|
|
21
.travis.yml
21
.travis.yml
@ -1,10 +1,9 @@
|
|||||||
language: php
|
language: php
|
||||||
|
|
||||||
php:
|
php:
|
||||||
- 5.4
|
|
||||||
- 5.5
|
|
||||||
- 5.6
|
- 5.6
|
||||||
- 7.0
|
- 7.0
|
||||||
|
- nightly
|
||||||
- hhvm
|
- hhvm
|
||||||
|
|
||||||
env:
|
env:
|
||||||
@ -28,14 +27,6 @@ after_script:
|
|||||||
|
|
||||||
matrix:
|
matrix:
|
||||||
include:
|
include:
|
||||||
- php: 5.4
|
|
||||||
env: DB=mariadb
|
|
||||||
addons:
|
|
||||||
mariadb: 5.5
|
|
||||||
- php: 5.5
|
|
||||||
env: DB=mariadb
|
|
||||||
addons:
|
|
||||||
mariadb: 5.5
|
|
||||||
- php: 5.6
|
- php: 5.6
|
||||||
env: DB=mariadb
|
env: DB=mariadb
|
||||||
addons:
|
addons:
|
||||||
@ -49,14 +40,6 @@ matrix:
|
|||||||
addons:
|
addons:
|
||||||
mariadb: 5.5
|
mariadb: 5.5
|
||||||
|
|
||||||
- php: 5.4
|
|
||||||
env: DB=mariadb
|
|
||||||
addons:
|
|
||||||
mariadb: 10.1
|
|
||||||
- php: 5.5
|
|
||||||
env: DB=mariadb
|
|
||||||
addons:
|
|
||||||
mariadb: 10.1
|
|
||||||
- php: 5.6
|
- php: 5.6
|
||||||
env: DB=mariadb
|
env: DB=mariadb
|
||||||
addons:
|
addons:
|
||||||
@ -72,6 +55,8 @@ matrix:
|
|||||||
exclude:
|
exclude:
|
||||||
- php: hhvm
|
- php: hhvm
|
||||||
env: DB=pgsql # driver for PostgreSQL currently unsupported by HHVM, requires 3rd party dependency
|
env: DB=pgsql # driver for PostgreSQL currently unsupported by HHVM, requires 3rd party dependency
|
||||||
|
allow_failures:
|
||||||
|
- php: nightly
|
||||||
|
|
||||||
sudo: false
|
sudo: false
|
||||||
|
|
||||||
|
10
README.md
10
README.md
@ -3,7 +3,7 @@
|
|||||||
| [![Build status][Master image]][Master] | [![Build status][2.5 image]][2.5] |
|
| [![Build status][Master image]][Master] | [![Build status][2.5 image]][2.5] |
|
||||||
| [![Coverage Status][Master coverage image]][Master coverage] | [![Coverage Status][2.5 coverage image]][2.5 coverage] |
|
| [![Coverage Status][Master coverage image]][Master coverage] | [![Coverage Status][2.5 coverage image]][2.5 coverage] |
|
||||||
|
|
||||||
Doctrine 2 is an object-relational mapper (ORM) for PHP 5.4+ that provides transparent persistence
|
Doctrine 2 is an object-relational mapper (ORM) for PHP 5.6+ that provides transparent persistence
|
||||||
for PHP objects. It sits on top of a powerful database abstraction layer (DBAL). One of its key features
|
for PHP objects. It sits on top of a powerful database abstraction layer (DBAL). One of its key features
|
||||||
is the option to write database queries in a proprietary object oriented SQL dialect called Doctrine Query Language (DQL),
|
is the option to write database queries in a proprietary object oriented SQL dialect called Doctrine Query Language (DQL),
|
||||||
inspired by Hibernate's HQL. This provides developers with a powerful alternative to SQL that maintains flexibility
|
inspired by Hibernate's HQL. This provides developers with a powerful alternative to SQL that maintains flexibility
|
||||||
@ -18,9 +18,9 @@ without requiring unnecessary code duplication.
|
|||||||
|
|
||||||
[Master image]: https://img.shields.io/travis/doctrine/doctrine2/master.svg?style=flat-square
|
[Master image]: https://img.shields.io/travis/doctrine/doctrine2/master.svg?style=flat-square
|
||||||
[Master]: https://travis-ci.org/doctrine/doctrine2
|
[Master]: https://travis-ci.org/doctrine/doctrine2
|
||||||
[Master coverage image]: https://img.shields.io/coveralls/doctrine/doctrine2/master.svg?style=flat-square
|
[Master coverage image]: https://img.shields.io/scrutinizer/coverage/g/doctrine/doctrine2/master.svg?style=flat-square
|
||||||
[Master coverage]: https://coveralls.io/r/doctrine/doctrine2?branch=master
|
[Master coverage]: https://scrutinizer-ci.com/g/doctrine/doctrine2/?branch=master
|
||||||
[2.5 image]: https://img.shields.io/travis/doctrine/doctrine2/2.5.svg?style=flat-square
|
[2.5 image]: https://img.shields.io/travis/doctrine/doctrine2/2.5.svg?style=flat-square
|
||||||
[2.5]: https://github.com/doctrine/doctrine2/tree/2.5
|
[2.5]: https://github.com/doctrine/doctrine2/tree/2.5
|
||||||
[2.5 coverage image]: https://img.shields.io/coveralls/doctrine/doctrine2/2.5.svg?style=flat-square
|
[2.5 coverage image]: https://img.shields.io/scrutinizer/coverage/g/doctrine/doctrine2/2.5.svg?style=flat-square
|
||||||
[2.5 coverage]: https://coveralls.io/r/doctrine/doctrine2?branch=2.5
|
[2.5 coverage]: https://scrutinizer-ci.com/g/doctrine/doctrine2/?branch=2.5
|
||||||
|
@ -1,5 +1,11 @@
|
|||||||
# Upgrade to 2.5
|
# Upgrade to 2.5
|
||||||
|
|
||||||
|
## Minor BC BREAK: query cache key time is now a float
|
||||||
|
|
||||||
|
As of 2.5.5, the `QueryCacheEntry#time` property will contain a float value
|
||||||
|
instead of an integer in order to have more precision and also to be consistent
|
||||||
|
with the `TimestampCacheEntry#time`.
|
||||||
|
|
||||||
## Minor BC BREAK: discriminator map must now include all non-transient classes
|
## Minor BC BREAK: discriminator map must now include all non-transient classes
|
||||||
|
|
||||||
It is now required that you declare the root of an inheritance in the
|
It is now required that you declare the root of an inheritance in the
|
||||||
|
@ -31,7 +31,7 @@ $helperSet = null;
|
|||||||
if (file_exists($configFile)) {
|
if (file_exists($configFile)) {
|
||||||
if ( ! is_readable($configFile)) {
|
if ( ! is_readable($configFile)) {
|
||||||
trigger_error(
|
trigger_error(
|
||||||
'Configuration file [' . $configFile . '] does not have read permission.', E_ERROR
|
'Configuration file [' . $configFile . '] does not have read permission.', E_USER_ERROR
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
],
|
],
|
||||||
"minimum-stability": "dev",
|
"minimum-stability": "dev",
|
||||||
"require": {
|
"require": {
|
||||||
"php": ">=5.4",
|
"php": "^5.6 || ^7.0",
|
||||||
"ext-pdo": "*",
|
"ext-pdo": "*",
|
||||||
"doctrine/collections": "~1.2",
|
"doctrine/collections": "~1.2",
|
||||||
"doctrine/dbal": ">=2.5-dev,<2.7-dev",
|
"doctrine/dbal": ">=2.5-dev,<2.7-dev",
|
||||||
@ -25,7 +25,7 @@
|
|||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"symfony/yaml": "~2.3|~3.0",
|
"symfony/yaml": "~2.3|~3.0",
|
||||||
"phpunit/phpunit": "~4.0"
|
"phpunit/phpunit": "^5.4"
|
||||||
},
|
},
|
||||||
"suggest": {
|
"suggest": {
|
||||||
"symfony/yaml": "If you want to use YAML Metadata Mapping Driver"
|
"symfony/yaml": "If you want to use YAML Metadata Mapping Driver"
|
||||||
@ -43,6 +43,6 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"archive": {
|
"archive": {
|
||||||
"exclude": ["!vendor", "tests", "*phpunit.xml", ".travis.yml", "build.xml", "build.properties", "composer.phar", "vendor/satooshi", "lib/vendor", "*.swp", "*coveralls.yml"]
|
"exclude": ["!vendor", "tests", "*phpunit.xml", ".travis.yml", "build.xml", "build.properties", "composer.phar", "vendor/satooshi", "lib/vendor", "*.swp"]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -98,7 +98,7 @@ For example for the previous enum type:
|
|||||||
|
|
||||||
public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $platform)
|
public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $platform)
|
||||||
{
|
{
|
||||||
return "ENUM('visible', 'invisible') COMMENT '(DC2Type:enumvisibility)'";
|
return "ENUM('visible', 'invisible')";
|
||||||
}
|
}
|
||||||
|
|
||||||
public function convertToPHPValue($value, AbstractPlatform $platform)
|
public function convertToPHPValue($value, AbstractPlatform $platform)
|
||||||
@ -118,6 +118,11 @@ For example for the previous enum type:
|
|||||||
{
|
{
|
||||||
return self::ENUM_VISIBILITY;
|
return self::ENUM_VISIBILITY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function requiresSQLCommentHint(AbstractPlatform $platform)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
You can register this type with ``Type::addType('enumvisibility', 'MyProject\DBAL\EnumVisibilityType');``.
|
You can register this type with ``Type::addType('enumvisibility', 'MyProject\DBAL\EnumVisibilityType');``.
|
||||||
@ -152,7 +157,7 @@ You can generalize this approach easily to create a base class for enums:
|
|||||||
{
|
{
|
||||||
$values = array_map(function($val) { return "'".$val."'"; }, $this->values);
|
$values = array_map(function($val) { return "'".$val."'"; }, $this->values);
|
||||||
|
|
||||||
return "ENUM(".implode(", ", $values).") COMMENT '(DC2Type:".$this->name.")'";
|
return "ENUM(".implode(", ", $values).")";
|
||||||
}
|
}
|
||||||
|
|
||||||
public function convertToPHPValue($value, AbstractPlatform $platform)
|
public function convertToPHPValue($value, AbstractPlatform $platform)
|
||||||
@ -172,6 +177,11 @@ You can generalize this approach easily to create a base class for enums:
|
|||||||
{
|
{
|
||||||
return $this->name;
|
return $this->name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function requiresSQLCommentHint(AbstractPlatform $platform)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
With this base class you can define an enum as easily as:
|
With this base class you can define an enum as easily as:
|
||||||
|
@ -49,7 +49,7 @@ By default Doctrine assumes that you are working with a default timezone. Each D
|
|||||||
is created by Doctrine will be assigned the timezone that is currently the default, either through
|
is created by Doctrine will be assigned the timezone that is currently the default, either through
|
||||||
the ``date.timezone`` ini setting or by calling ``date_default_timezone_set()``.
|
the ``date.timezone`` ini setting or by calling ``date_default_timezone_set()``.
|
||||||
|
|
||||||
This is very important to handle correctly if your application runs on different serves or is moved from one to another server
|
This is very important to handle correctly if your application runs on different servers or is moved from one to another server
|
||||||
(with different timezone settings). You have to make sure that the timezone is the correct one
|
(with different timezone settings). You have to make sure that the timezone is the correct one
|
||||||
on all this systems.
|
on all this systems.
|
||||||
|
|
||||||
|
@ -394,7 +394,7 @@ means that you have to register a special autoloader for these classes:
|
|||||||
.. code-block:: php
|
.. code-block:: php
|
||||||
|
|
||||||
<?php
|
<?php
|
||||||
use Doctrine\ORM\Proxy\Autoloader;
|
use Doctrine\Common\Proxy\Autoloader;
|
||||||
|
|
||||||
$proxyDir = "/path/to/proxies";
|
$proxyDir = "/path/to/proxies";
|
||||||
$proxyNamespace = "MyProxies";
|
$proxyNamespace = "MyProxies";
|
||||||
|
@ -37,8 +37,11 @@ Index
|
|||||||
- :ref:`@ColumnResult <annref_column_result>`
|
- :ref:`@ColumnResult <annref_column_result>`
|
||||||
- :ref:`@Cache <annref_cache>`
|
- :ref:`@Cache <annref_cache>`
|
||||||
- :ref:`@ChangeTrackingPolicy <annref_changetrackingpolicy>`
|
- :ref:`@ChangeTrackingPolicy <annref_changetrackingpolicy>`
|
||||||
|
- :ref:`@CustomIdGenerator <annref_customidgenerator>`
|
||||||
- :ref:`@DiscriminatorColumn <annref_discriminatorcolumn>`
|
- :ref:`@DiscriminatorColumn <annref_discriminatorcolumn>`
|
||||||
- :ref:`@DiscriminatorMap <annref_discriminatormap>`
|
- :ref:`@DiscriminatorMap <annref_discriminatormap>`
|
||||||
|
- :ref:`@Embeddable <annref_embeddable>`
|
||||||
|
- :ref:`@Embedded <annref_embedded>`
|
||||||
- :ref:`@Entity <annref_entity>`
|
- :ref:`@Entity <annref_entity>`
|
||||||
- :ref:`@EntityResult <annref_entity_result>`
|
- :ref:`@EntityResult <annref_entity_result>`
|
||||||
- :ref:`@FieldResult <annref_field_result>`
|
- :ref:`@FieldResult <annref_field_result>`
|
||||||
@ -231,6 +234,30 @@ Example:
|
|||||||
*/
|
*/
|
||||||
class User {}
|
class User {}
|
||||||
|
|
||||||
|
.. _annref_customidgenerator:
|
||||||
|
|
||||||
|
@CustomIdGenerator
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
This annotations allows you to specify a user-provided class to generate identifiers. This annotation only works when both :ref:`@Id <annref_id>` and :ref:`@GeneratedValue(strategy="CUSTOM") <annref_generatedvalue>` are specified.
|
||||||
|
|
||||||
|
Required attributes:
|
||||||
|
|
||||||
|
- **class**: name of the class which should extend Doctrine\ORM\Id\AbstractIdGenerator
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
.. code-block:: php
|
||||||
|
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @Id
|
||||||
|
* @Column(type="integer")
|
||||||
|
* @GeneratedValue(strategy="CUSTOM")
|
||||||
|
* @CustomIdGenerator(class="My\Namespace\MyIdGenerator")
|
||||||
|
*/
|
||||||
|
public $id;
|
||||||
|
|
||||||
.. _annref_discriminatorcolumn:
|
.. _annref_discriminatorcolumn:
|
||||||
|
|
||||||
@DiscriminatorColumn
|
@DiscriminatorColumn
|
||||||
@ -282,6 +309,67 @@ depending on whether the classes are in the namespace or not.
|
|||||||
// ...
|
// ...
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.. _annref_embeddable:
|
||||||
|
|
||||||
|
@Embeddable
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
The embeddable is required on an entity targeted to be embeddable inside
|
||||||
|
another. It works together with the :ref:`@Embedded <annref_embedded>`
|
||||||
|
annotation to establish the relationship between two entities.
|
||||||
|
|
||||||
|
.. code-block:: php
|
||||||
|
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Embeddable
|
||||||
|
*/
|
||||||
|
class Address
|
||||||
|
{
|
||||||
|
// ...
|
||||||
|
class User
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @Embedded(class = "Address")
|
||||||
|
*/
|
||||||
|
private $address;
|
||||||
|
|
||||||
|
|
||||||
|
.. _annref_embedded:
|
||||||
|
|
||||||
|
@Embedded
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
The embedded annotation is required on a member class varible targed to
|
||||||
|
embed it's class argument inside it's own class.
|
||||||
|
|
||||||
|
Required attributes:
|
||||||
|
|
||||||
|
- **class**: The embeddable class
|
||||||
|
|
||||||
|
|
||||||
|
.. code-block:: php
|
||||||
|
|
||||||
|
<?php
|
||||||
|
|
||||||
|
// ...
|
||||||
|
class User
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @Embedded(class = "Address")
|
||||||
|
*/
|
||||||
|
private $address;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Embeddable
|
||||||
|
*/
|
||||||
|
class Address
|
||||||
|
{
|
||||||
|
// ...
|
||||||
|
|
||||||
|
|
||||||
.. _annref_entity:
|
.. _annref_entity:
|
||||||
|
|
||||||
@Entity
|
@Entity
|
||||||
|
@ -909,7 +909,7 @@ An instance of the ``Doctrine\ORM\Query`` class represents a DQL
|
|||||||
query. You create a Query instance be calling
|
query. You create a Query instance be calling
|
||||||
``EntityManager#createQuery($dql)``, passing the DQL query string.
|
``EntityManager#createQuery($dql)``, passing the DQL query string.
|
||||||
Alternatively you can create an empty ``Query`` instance and invoke
|
Alternatively you can create an empty ``Query`` instance and invoke
|
||||||
``Query#setDql($dql)`` afterwards. Here are some examples:
|
``Query#setDQL($dql)`` afterwards. Here are some examples:
|
||||||
|
|
||||||
.. code-block:: php
|
.. code-block:: php
|
||||||
|
|
||||||
@ -919,9 +919,9 @@ Alternatively you can create an empty ``Query`` instance and invoke
|
|||||||
// example1: passing a DQL string
|
// example1: passing a DQL string
|
||||||
$q = $em->createQuery('select u from MyProject\Model\User u');
|
$q = $em->createQuery('select u from MyProject\Model\User u');
|
||||||
|
|
||||||
// example2: using setDql
|
// example2: using setDQL
|
||||||
$q = $em->createQuery();
|
$q = $em->createQuery();
|
||||||
$q->setDql('select u from MyProject\Model\User u');
|
$q->setDQL('select u from MyProject\Model\User u');
|
||||||
|
|
||||||
Query Result Formats
|
Query Result Formats
|
||||||
~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~
|
||||||
|
@ -179,7 +179,7 @@ the life-time of their registered entities.
|
|||||||
allows providing fallback metadata even when no actual metadata exists
|
allows providing fallback metadata even when no actual metadata exists
|
||||||
or could be found. This event is not a lifecycle callback.
|
or could be found. This event is not a lifecycle callback.
|
||||||
- preFlush - The preFlush event occurs at the very beginning of a flush
|
- preFlush - The preFlush event occurs at the very beginning of a flush
|
||||||
operation. This event is not a lifecycle callback.
|
operation.
|
||||||
- onFlush - The onFlush event occurs after the change-sets of all
|
- onFlush - The onFlush event occurs after the change-sets of all
|
||||||
managed entities are computed. This event is not a lifecycle
|
managed entities are computed. This event is not a lifecycle
|
||||||
callback.
|
callback.
|
||||||
@ -406,8 +406,8 @@ behaviors across different entity classes.
|
|||||||
|
|
||||||
Note that they require much more detailed knowledge about the inner
|
Note that they require much more detailed knowledge about the inner
|
||||||
workings of the EntityManager and UnitOfWork. Please read the
|
workings of the EntityManager and UnitOfWork. Please read the
|
||||||
*Implementing Event Listeners* section carefully if you are trying
|
:ref:`reference-events-implementing-listeners` section carefully if you
|
||||||
to write your own listener.
|
are trying to write your own listener.
|
||||||
|
|
||||||
For event subscribers, there are no surprises. They declare the
|
For event subscribers, there are no surprises. They declare the
|
||||||
lifecycle events in their ``getSubscribedEvents`` method and provide
|
lifecycle events in their ``getSubscribedEvents`` method and provide
|
||||||
@ -434,7 +434,7 @@ A lifecycle event listener looks like the following:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
A lifecycle event subscriber may looks like this:
|
A lifecycle event subscriber may look like this:
|
||||||
|
|
||||||
.. code-block:: php
|
.. code-block:: php
|
||||||
|
|
||||||
|
@ -113,7 +113,7 @@ suggested standard way to build queries:
|
|||||||
$qb->expr()->eq('u.id', '?1'),
|
$qb->expr()->eq('u.id', '?1'),
|
||||||
$qb->expr()->like('u.nickname', '?2')
|
$qb->expr()->like('u.nickname', '?2')
|
||||||
))
|
))
|
||||||
->orderBy('u.surname', 'ASC'));
|
->orderBy('u.surname', 'ASC');
|
||||||
|
|
||||||
Here is a complete list of helper methods available in ``QueryBuilder``:
|
Here is a complete list of helper methods available in ``QueryBuilder``:
|
||||||
|
|
||||||
|
@ -153,21 +153,21 @@ Built-in cached persisters
|
|||||||
|
|
||||||
Cached persisters are responsible to access cache regions.
|
Cached persisters are responsible to access cache regions.
|
||||||
|
|
||||||
+-----------------------+-------------------------------------------------------------------------------+
|
+-----------------------+-------------------------------------------------------------------------------------------+
|
||||||
| Cache Usage | Persister |
|
| Cache Usage | Persister |
|
||||||
+=======================+===============================================================================+
|
+=======================+===========================================================================================+
|
||||||
| READ_ONLY | Doctrine\\ORM\\Cache\\Persister\\ReadOnlyCachedEntityPersister |
|
| READ_ONLY | Doctrine\\ORM\\Cache\\Persister\\Entity\\ReadOnlyCachedEntityPersister |
|
||||||
+-----------------------+-------------------------------------------------------------------------------+
|
+-----------------------+-------------------------------------------------------------------------------------------+
|
||||||
| READ_WRITE | Doctrine\\ORM\\Cache\\Persister\\ReadWriteCachedEntityPersister |
|
| READ_WRITE | Doctrine\\ORM\\Cache\\Persister\\Entity\\ReadWriteCachedEntityPersister |
|
||||||
+-----------------------+-------------------------------------------------------------------------------+
|
+-----------------------+-------------------------------------------------------------------------------------------+
|
||||||
| NONSTRICT_READ_WRITE | Doctrine\\ORM\\Cache\\Persister\\NonStrictReadWriteCachedEntityPersister |
|
| NONSTRICT_READ_WRITE | Doctrine\\ORM\\Cache\\Persister\\Entity\\NonStrictReadWriteCachedEntityPersister |
|
||||||
+-----------------------+-------------------------------------------------------------------------------+
|
+-----------------------+-------------------------------------------------------------------------------------------+
|
||||||
| READ_ONLY | Doctrine\\ORM\\Cache\\Persister\\ReadOnlyCachedCollectionPersister |
|
| READ_ONLY | Doctrine\\ORM\\Cache\\Persister\\Collection\\ReadOnlyCachedCollectionPersister |
|
||||||
+-----------------------+-------------------------------------------------------------------------------+
|
+-----------------------+-------------------------------------------------------------------------------------------+
|
||||||
| READ_WRITE | Doctrine\\ORM\\Cache\\Persister\\ReadWriteCachedCollectionPersister |
|
| READ_WRITE | Doctrine\\ORM\\Cache\\Persister\\Collection\\ReadWriteCachedCollectionPersister |
|
||||||
+-----------------------+-------------------------------------------------------------------------------+
|
+-----------------------+-------------------------------------------------------------------------------------------+
|
||||||
| NONSTRICT_READ_WRITE | Doctrine\\ORM\\Cache\\Persister\\NonStrictReadWriteCacheCollectionPersister |
|
| NONSTRICT_READ_WRITE | Doctrine\\ORM\\Cache\\Persister\\Collection\\NonStrictReadWriteCachedCollectionPersister |
|
||||||
+-----------------------+-------------------------------------------------------------------------------+
|
+-----------------------+-------------------------------------------------------------------------------------------+
|
||||||
|
|
||||||
Configuration
|
Configuration
|
||||||
-------------
|
-------------
|
||||||
|
@ -32,7 +32,7 @@ You can consider the following APIs to be safe from SQL injection:
|
|||||||
- Queries through the Criteria API on ``Doctrine\ORM\PersistentCollection`` and
|
- Queries through the Criteria API on ``Doctrine\ORM\PersistentCollection`` and
|
||||||
``Doctrine\ORM\EntityRepository``.
|
``Doctrine\ORM\EntityRepository``.
|
||||||
|
|
||||||
You are **NOT** save from SQL injection when using user input with:
|
You are **NOT** safe from SQL injection when using user input with:
|
||||||
|
|
||||||
- Expression API of ``Doctrine\ORM\QueryBuilder``
|
- Expression API of ``Doctrine\ORM\QueryBuilder``
|
||||||
- Concatenating user input into DQL SELECT, UPDATE or DELETE statements or
|
- Concatenating user input into DQL SELECT, UPDATE or DELETE statements or
|
||||||
|
@ -699,8 +699,6 @@ You can also load by owning side associations through the repository:
|
|||||||
$number = $em->find('MyProject\Domain\Phonenumber', 1234);
|
$number = $em->find('MyProject\Domain\Phonenumber', 1234);
|
||||||
$user = $em->getRepository('MyProject\Domain\User')->findOneBy(array('phone' => $number->getId()));
|
$user = $em->getRepository('MyProject\Domain\User')->findOneBy(array('phone' => $number->getId()));
|
||||||
|
|
||||||
Be careful that this only works by passing the ID of the associated entity, not yet by passing the associated entity itself.
|
|
||||||
|
|
||||||
The ``EntityRepository#findBy()`` method additionally accepts orderings, limit and offset as second to fourth parameters:
|
The ``EntityRepository#findBy()`` method additionally accepts orderings, limit and offset as second to fourth parameters:
|
||||||
|
|
||||||
.. code-block:: php
|
.. code-block:: php
|
||||||
@ -729,6 +727,14 @@ examples are equivalent:
|
|||||||
// A single user by its nickname (__call magic)
|
// A single user by its nickname (__call magic)
|
||||||
$user = $em->getRepository('MyProject\Domain\User')->findOneByNickname('romanb');
|
$user = $em->getRepository('MyProject\Domain\User')->findOneByNickname('romanb');
|
||||||
|
|
||||||
|
Additionally, you can just count the result of the provided conditions when you don't really need the data:
|
||||||
|
|
||||||
|
.. code-block:: php
|
||||||
|
|
||||||
|
<?php
|
||||||
|
// Check there is no user with nickname
|
||||||
|
$availableNickname = 0 === $em->getRepository('MyProject\Domain\User')->count(['nickname' => 'nonexistent']);
|
||||||
|
|
||||||
By Criteria
|
By Criteria
|
||||||
~~~~~~~~~~~
|
~~~~~~~~~~~
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
Separating Concerns using Embeddables
|
Separating Concerns using Embeddables
|
||||||
-------------------------------------
|
-------------------------------------
|
||||||
|
|
||||||
Embeddables are classes which are not entities themself, but are embedded
|
Embeddables are classes which are not entities themselves, but are embedded
|
||||||
in entities and can also be queried in DQL. You'll mostly want to use them
|
in entities and can also be queried in DQL. You'll mostly want to use them
|
||||||
to reduce duplication or separating concerns. Value objects such as date range
|
to reduce duplication or separating concerns. Value objects such as date range
|
||||||
or address are the primary use case for this feature. Embeddables can only
|
or address are the primary use case for this feature. Embeddables can only
|
||||||
|
@ -17,7 +17,7 @@ This guide is designed for beginners that haven't worked with Doctrine ORM
|
|||||||
before. There are some prerequesites for the tutorial that have to be
|
before. There are some prerequesites for the tutorial that have to be
|
||||||
installed:
|
installed:
|
||||||
|
|
||||||
- PHP 5.4 or above
|
- PHP (latest stable version)
|
||||||
- Composer Package Manager (`Install Composer
|
- Composer Package Manager (`Install Composer
|
||||||
<http://getcomposer.org/doc/00-intro.md>`_)
|
<http://getcomposer.org/doc/00-intro.md>`_)
|
||||||
|
|
||||||
@ -344,7 +344,7 @@ Now that we have defined our first entity, let's update the database:
|
|||||||
|
|
||||||
$ vendor/bin/doctrine orm:schema-tool:update --force --dump-sql
|
$ vendor/bin/doctrine orm:schema-tool:update --force --dump-sql
|
||||||
|
|
||||||
Specifying both flags ``--force`` and ``-dump-sql`` prints and executes the DDL
|
Specifying both flags ``--force`` and ``--dump-sql`` prints and executes the DDL
|
||||||
statements.
|
statements.
|
||||||
|
|
||||||
Now create a new script that will insert products into the database:
|
Now create a new script that will insert products into the database:
|
||||||
@ -616,12 +616,12 @@ domain model to match the requirements:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Whenever an entity is recreated from the database, an Collection
|
You use Doctrine's ArrayCollections in your Doctrine models, rather
|
||||||
implementation of the type Doctrine is injected into your entity
|
than plain PHP arrays, so that Doctrine can watch what happens with
|
||||||
instead of an array. Compared to the ArrayCollection this
|
them and act appropriately. Note that if you dump your entities,
|
||||||
implementation helps the Doctrine ORM understand the changes that
|
you'll see a "PersistentCollection" in place of your ArrayCollection,
|
||||||
have happened to the collection which are noteworthy for
|
which is just an
|
||||||
persistence.
|
internal Doctrine class with the same interface.
|
||||||
|
|
||||||
.. warning::
|
.. warning::
|
||||||
|
|
||||||
@ -1535,6 +1535,16 @@ As an example here is the code of the first use case "List of Bugs":
|
|||||||
Using EntityRepositories you can avoid coupling your model with specific query logic.
|
Using EntityRepositories you can avoid coupling your model with specific query logic.
|
||||||
You can also re-use query logic easily throughout your application.
|
You can also re-use query logic easily throughout your application.
|
||||||
|
|
||||||
|
The method ``count()`` takes an array of fields or association keys and the values to match against.
|
||||||
|
This provides you with a convenient and lightweight way to count a resultset when you don't need to
|
||||||
|
deal with it:
|
||||||
|
|
||||||
|
.. code-block:: php
|
||||||
|
|
||||||
|
<?php
|
||||||
|
$productCount = $entityManager->getRepository(Product::class)
|
||||||
|
->count(['name' => $productName]);
|
||||||
|
|
||||||
Conclusion
|
Conclusion
|
||||||
----------
|
----------
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@ use Doctrine\ORM\Cache\QueryCacheKey;
|
|||||||
use Doctrine\DBAL\Cache\QueryCacheProfile;
|
use Doctrine\DBAL\Cache\QueryCacheProfile;
|
||||||
|
|
||||||
use Doctrine\ORM\Cache;
|
use Doctrine\ORM\Cache;
|
||||||
use Doctrine\ORM\Query\QueryException;
|
use Doctrine\ORM\Query\ResultSetMapping;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base contract for ORM queries. Base class for Query and NativeQuery.
|
* Base contract for ORM queries. Base class for Query and NativeQuery.
|
||||||
@ -719,7 +719,7 @@ abstract class AbstractQuery
|
|||||||
*
|
*
|
||||||
* @param int $hydrationMode
|
* @param int $hydrationMode
|
||||||
*
|
*
|
||||||
* @return array
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
public function getResult($hydrationMode = self::HYDRATE_OBJECT)
|
public function getResult($hydrationMode = self::HYDRATE_OBJECT)
|
||||||
{
|
{
|
||||||
@ -992,32 +992,54 @@ abstract class AbstractQuery
|
|||||||
private function executeUsingQueryCache($parameters = null, $hydrationMode = null)
|
private function executeUsingQueryCache($parameters = null, $hydrationMode = null)
|
||||||
{
|
{
|
||||||
$rsm = $this->getResultSetMapping();
|
$rsm = $this->getResultSetMapping();
|
||||||
$querykey = new QueryCacheKey($this->getHash(), $this->lifetime, $this->cacheMode ?: Cache::MODE_NORMAL);
|
|
||||||
$queryCache = $this->_em->getCache()->getQueryCache($this->cacheRegion);
|
$queryCache = $this->_em->getCache()->getQueryCache($this->cacheRegion);
|
||||||
$result = $queryCache->get($querykey, $rsm, $this->_hints);
|
$queryKey = new QueryCacheKey(
|
||||||
|
$this->getHash(),
|
||||||
|
$this->lifetime,
|
||||||
|
$this->cacheMode ?: Cache::MODE_NORMAL,
|
||||||
|
$this->getTimestampKey()
|
||||||
|
);
|
||||||
|
|
||||||
|
$result = $queryCache->get($queryKey, $rsm, $this->_hints);
|
||||||
|
|
||||||
if ($result !== null) {
|
if ($result !== null) {
|
||||||
if ($this->cacheLogger) {
|
if ($this->cacheLogger) {
|
||||||
$this->cacheLogger->queryCacheHit($queryCache->getRegion()->getName(), $querykey);
|
$this->cacheLogger->queryCacheHit($queryCache->getRegion()->getName(), $queryKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
$result = $this->executeIgnoreQueryCache($parameters, $hydrationMode);
|
$result = $this->executeIgnoreQueryCache($parameters, $hydrationMode);
|
||||||
$cached = $queryCache->put($querykey, $rsm, $result, $this->_hints);
|
$cached = $queryCache->put($queryKey, $rsm, $result, $this->_hints);
|
||||||
|
|
||||||
if ($this->cacheLogger) {
|
if ($this->cacheLogger) {
|
||||||
$this->cacheLogger->queryCacheMiss($queryCache->getRegion()->getName(), $querykey);
|
$this->cacheLogger->queryCacheMiss($queryCache->getRegion()->getName(), $queryKey);
|
||||||
|
|
||||||
if ($cached) {
|
if ($cached) {
|
||||||
$this->cacheLogger->queryCachePut($queryCache->getRegion()->getName(), $querykey);
|
$this->cacheLogger->queryCachePut($queryCache->getRegion()->getName(), $queryKey);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return \Doctrine\ORM\Cache\TimestampCacheKey|null
|
||||||
|
*/
|
||||||
|
private function getTimestampKey()
|
||||||
|
{
|
||||||
|
$entityName = reset($this->_resultSetMapping->aliasMap);
|
||||||
|
|
||||||
|
if (empty($entityName)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$metadata = $this->_em->getClassMetadata($entityName);
|
||||||
|
|
||||||
|
return new Cache\TimestampCacheKey($metadata->getTableName());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the result cache id to use to store the result set cache entry.
|
* Get the result cache id to use to store the result set cache entry.
|
||||||
* Will return the configured id if it exists otherwise a hash will be
|
* Will return the configured id if it exists otherwise a hash will be
|
||||||
|
@ -110,7 +110,9 @@ class CacheConfiguration
|
|||||||
public function getQueryValidator()
|
public function getQueryValidator()
|
||||||
{
|
{
|
||||||
if ($this->queryValidator === null) {
|
if ($this->queryValidator === null) {
|
||||||
$this->queryValidator = new TimestampQueryCacheValidator();
|
$this->queryValidator = new TimestampQueryCacheValidator(
|
||||||
|
$this->cacheFactory->getTimestampRegion()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->queryValidator;
|
return $this->queryValidator;
|
||||||
|
@ -217,8 +217,8 @@ class DefaultCacheFactory implements CacheFactory
|
|||||||
|
|
||||||
if ( ! $this->fileLockRegionDirectory) {
|
if ( ! $this->fileLockRegionDirectory) {
|
||||||
throw new \LogicException(
|
throw new \LogicException(
|
||||||
'If you what to use a "READ_WRITE" cache an implementation of "Doctrine\ORM\Cache\ConcurrentRegion" is required, ' .
|
'If you want to use a "READ_WRITE" cache an implementation of "Doctrine\ORM\Cache\ConcurrentRegion" is required, ' .
|
||||||
'The default implementation provided by doctrine is "Doctrine\ORM\Cache\Region\FileLockRegion" if you what to use it please provide a valid directory, DefaultCacheFactory#setFileLockRegionDirectory(). '
|
'The default implementation provided by doctrine is "Doctrine\ORM\Cache\Region\FileLockRegion" if you want to use it please provide a valid directory, DefaultCacheFactory#setFileLockRegionDirectory(). '
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -233,8 +233,8 @@ class DefaultQueryCache implements QueryCache
|
|||||||
|
|
||||||
$data = array();
|
$data = array();
|
||||||
$entityName = reset($rsm->aliasMap);
|
$entityName = reset($rsm->aliasMap);
|
||||||
|
$rootAlias = key($rsm->aliasMap);
|
||||||
$hasRelation = ( ! empty($rsm->relationMap));
|
$hasRelation = ( ! empty($rsm->relationMap));
|
||||||
$metadata = $this->em->getClassMetadata($entityName);
|
|
||||||
$persister = $this->uow->getEntityPersister($entityName);
|
$persister = $this->uow->getEntityPersister($entityName);
|
||||||
|
|
||||||
if ( ! ($persister instanceof CachedPersister)) {
|
if ( ! ($persister instanceof CachedPersister)) {
|
||||||
@ -245,10 +245,11 @@ class DefaultQueryCache implements QueryCache
|
|||||||
|
|
||||||
foreach ($result as $index => $entity) {
|
foreach ($result as $index => $entity) {
|
||||||
$identifier = $this->uow->getEntityIdentifier($entity);
|
$identifier = $this->uow->getEntityIdentifier($entity);
|
||||||
|
$entityKey = new EntityCacheKey($entityName, $identifier);
|
||||||
$data[$index]['identifier'] = $identifier;
|
$data[$index]['identifier'] = $identifier;
|
||||||
$data[$index]['associations'] = array();
|
$data[$index]['associations'] = array();
|
||||||
|
|
||||||
if (($key->cacheMode & Cache::MODE_REFRESH) || ! $region->contains($entityKey = new EntityCacheKey($entityName, $identifier))) {
|
if (($key->cacheMode & Cache::MODE_REFRESH) || ! $region->contains($entityKey)) {
|
||||||
// Cancel put result if entity put fail
|
// Cancel put result if entity put fail
|
||||||
if ( ! $persister->storeEntityCache($entity, $entityKey)) {
|
if ( ! $persister->storeEntityCache($entity, $entityKey)) {
|
||||||
return false;
|
return false;
|
||||||
@ -261,37 +262,81 @@ class DefaultQueryCache implements QueryCache
|
|||||||
|
|
||||||
// @TODO - move to cache hydration components
|
// @TODO - move to cache hydration components
|
||||||
foreach ($rsm->relationMap as $alias => $name) {
|
foreach ($rsm->relationMap as $alias => $name) {
|
||||||
$metadata = $this->em->getClassMetadata($rsm->aliasMap[$rsm->parentAliasMap[$alias]]);
|
$parentAlias = $rsm->parentAliasMap[$alias];
|
||||||
|
$parentClass = $rsm->aliasMap[$parentAlias];
|
||||||
|
$metadata = $this->em->getClassMetadata($parentClass);
|
||||||
$assoc = $metadata->associationMappings[$name];
|
$assoc = $metadata->associationMappings[$name];
|
||||||
|
$assocValue = $this->getAssociationValue($rsm, $alias, $entity);
|
||||||
|
|
||||||
if (($assocValue = $metadata->getFieldValue($entity, $name)) === null || $assocValue instanceof Proxy) {
|
if ($assocValue === null) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
$assocPersister = $this->uow->getEntityPersister($assoc['targetEntity']);
|
// root entity association
|
||||||
$assocRegion = $assocPersister->getCacheRegion();
|
if ($rootAlias === $parentAlias) {
|
||||||
$assocMetadata = $assocPersister->getClassMetadata();
|
// Cancel put result if association put fail
|
||||||
|
if ( ($assocInfo = $this->storeAssociationCache($key, $assoc, $assocValue)) === null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Handle *-to-one associations
|
$data[$index]['associations'][$name] = $assocInfo;
|
||||||
if ($assoc['type'] & ClassMetadata::TO_ONE) {
|
|
||||||
|
|
||||||
$assocIdentifier = $this->uow->getEntityIdentifier($assocValue);
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (($key->cacheMode & Cache::MODE_REFRESH) || ! $assocRegion->contains($entityKey = new EntityCacheKey($assocMetadata->rootEntityName, $assocIdentifier))) {
|
// store single nested association
|
||||||
|
if ( ! is_array($assocValue)) {
|
||||||
|
// Cancel put result if association put fail
|
||||||
|
if ($this->storeAssociationCache($key, $assoc, $assocValue) === null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Cancel put result if association entity put fail
|
continue;
|
||||||
if ( ! $assocPersister->storeEntityCache($assocValue, $entityKey)) {
|
}
|
||||||
|
|
||||||
|
// store array of nested association
|
||||||
|
foreach ($assocValue as $aVal) {
|
||||||
|
// Cancel put result if association put fail
|
||||||
|
if ($this->storeAssociationCache($key, $assoc, $aVal) === null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$data[$index]['associations'][$name] = array(
|
return $this->region->put($key, new QueryCacheEntry($data));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param \Doctrine\ORM\Cache\QueryCacheKey $key
|
||||||
|
* @param array $assoc
|
||||||
|
* @param mixed $assocValue
|
||||||
|
*
|
||||||
|
* @return array|null
|
||||||
|
*/
|
||||||
|
private function storeAssociationCache(QueryCacheKey $key, array $assoc, $assocValue)
|
||||||
|
{
|
||||||
|
$assocPersister = $this->uow->getEntityPersister($assoc['targetEntity']);
|
||||||
|
$assocMetadata = $assocPersister->getClassMetadata();
|
||||||
|
$assocRegion = $assocPersister->getCacheRegion();
|
||||||
|
|
||||||
|
// Handle *-to-one associations
|
||||||
|
if ($assoc['type'] & ClassMetadata::TO_ONE) {
|
||||||
|
$assocIdentifier = $this->uow->getEntityIdentifier($assocValue);
|
||||||
|
$entityKey = new EntityCacheKey($assocMetadata->rootEntityName, $assocIdentifier);
|
||||||
|
|
||||||
|
if ( ! $assocValue instanceof Proxy && ($key->cacheMode & Cache::MODE_REFRESH) || ! $assocRegion->contains($entityKey)) {
|
||||||
|
// Entity put fail
|
||||||
|
if ( ! $assocPersister->storeEntityCache($assocValue, $entityKey)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return array(
|
||||||
'targetEntity' => $assocMetadata->rootEntityName,
|
'targetEntity' => $assocMetadata->rootEntityName,
|
||||||
'identifier' => $assocIdentifier,
|
'identifier' => $assocIdentifier,
|
||||||
'type' => $assoc['type']
|
'type' => $assoc['type']
|
||||||
);
|
);
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle *-to-many associations
|
// Handle *-to-many associations
|
||||||
@ -299,27 +344,86 @@ class DefaultQueryCache implements QueryCache
|
|||||||
|
|
||||||
foreach ($assocValue as $assocItemIndex => $assocItem) {
|
foreach ($assocValue as $assocItemIndex => $assocItem) {
|
||||||
$assocIdentifier = $this->uow->getEntityIdentifier($assocItem);
|
$assocIdentifier = $this->uow->getEntityIdentifier($assocItem);
|
||||||
|
$entityKey = new EntityCacheKey($assocMetadata->rootEntityName, $assocIdentifier);
|
||||||
|
|
||||||
if (($key->cacheMode & Cache::MODE_REFRESH) || ! $assocRegion->contains($entityKey = new EntityCacheKey($assocMetadata->rootEntityName, $assocIdentifier))) {
|
if (($key->cacheMode & Cache::MODE_REFRESH) || ! $assocRegion->contains($entityKey)) {
|
||||||
|
// Entity put fail
|
||||||
// Cancel put result if entity put fail
|
|
||||||
if ( ! $assocPersister->storeEntityCache($assocItem, $entityKey)) {
|
if ( ! $assocPersister->storeEntityCache($assocItem, $entityKey)) {
|
||||||
return false;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$list[$assocItemIndex] = $assocIdentifier;
|
$list[$assocItemIndex] = $assocIdentifier;
|
||||||
}
|
}
|
||||||
|
|
||||||
$data[$index]['associations'][$name] = array(
|
return array(
|
||||||
'targetEntity' => $assocMetadata->rootEntityName,
|
'targetEntity' => $assocMetadata->rootEntityName,
|
||||||
'type' => $assoc['type'],
|
'type' => $assoc['type'],
|
||||||
'list' => $list,
|
'list' => $list,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param \Doctrine\ORM\Query\ResultSetMapping $rsm
|
||||||
|
* @param string $assocAlias
|
||||||
|
* @param object $entity
|
||||||
|
*
|
||||||
|
* @return array|object
|
||||||
|
*/
|
||||||
|
private function getAssociationValue(ResultSetMapping $rsm, $assocAlias, $entity)
|
||||||
|
{
|
||||||
|
$path = array();
|
||||||
|
$alias = $assocAlias;
|
||||||
|
|
||||||
|
while (isset($rsm->parentAliasMap[$alias])) {
|
||||||
|
$parent = $rsm->parentAliasMap[$alias];
|
||||||
|
$field = $rsm->relationMap[$alias];
|
||||||
|
$class = $rsm->aliasMap[$parent];
|
||||||
|
|
||||||
|
array_unshift($path, array(
|
||||||
|
'field' => $field,
|
||||||
|
'class' => $class
|
||||||
|
));
|
||||||
|
|
||||||
|
$alias = $parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->region->put($key, new QueryCacheEntry($data));
|
return $this->getAssociationPathValue($entity, $path);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param mixed $value
|
||||||
|
* @param array $path
|
||||||
|
*
|
||||||
|
* @return array|object|null
|
||||||
|
*/
|
||||||
|
private function getAssociationPathValue($value, array $path)
|
||||||
|
{
|
||||||
|
$mapping = array_shift($path);
|
||||||
|
$metadata = $this->em->getClassMetadata($mapping['class']);
|
||||||
|
$assoc = $metadata->associationMappings[$mapping['field']];
|
||||||
|
$value = $metadata->getFieldValue($value, $mapping['field']);
|
||||||
|
|
||||||
|
if ($value === null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($path)) {
|
||||||
|
return $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle *-to-one associations
|
||||||
|
if ($assoc['type'] & ClassMetadata::TO_ONE) {
|
||||||
|
return $this->getAssociationPathValue($value, $path);
|
||||||
|
}
|
||||||
|
|
||||||
|
$values = array();
|
||||||
|
|
||||||
|
foreach ($value as $item) {
|
||||||
|
$values[] = $this->getAssociationPathValue($item, $path);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $values;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -71,7 +71,7 @@ class EntityCacheEntry implements CacheEntry
|
|||||||
/**
|
/**
|
||||||
* Retrieves the entity data resolving cache entries
|
* Retrieves the entity data resolving cache entries
|
||||||
*
|
*
|
||||||
* @param \Doctrine\ORM\EntityManagerInterfac $em
|
* @param \Doctrine\ORM\EntityManagerInterface $em
|
||||||
*
|
*
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
|
@ -287,17 +287,16 @@ abstract class AbstractEntityPersister implements CachedEntityPersister
|
|||||||
* @param array $orderBy
|
* @param array $orderBy
|
||||||
* @param integer $limit
|
* @param integer $limit
|
||||||
* @param integer $offset
|
* @param integer $offset
|
||||||
* @param integer $timestamp
|
|
||||||
*
|
*
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
protected function getHash($query, $criteria, array $orderBy = null, $limit = null, $offset = null, $timestamp = null)
|
protected function getHash($query, $criteria, array $orderBy = null, $limit = null, $offset = null)
|
||||||
{
|
{
|
||||||
list($params) = ($criteria instanceof Criteria)
|
list($params) = ($criteria instanceof Criteria)
|
||||||
? $this->persister->expandCriteriaParameters($criteria)
|
? $this->persister->expandCriteriaParameters($criteria)
|
||||||
: $this->persister->expandParameters($criteria);
|
: $this->persister->expandParameters($criteria);
|
||||||
|
|
||||||
return sha1($query . serialize($params) . serialize($orderBy) . $limit . $offset . $timestamp);
|
return sha1($query . serialize($params) . serialize($orderBy) . $limit . $offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -368,17 +367,16 @@ abstract class AbstractEntityPersister implements CachedEntityPersister
|
|||||||
}
|
}
|
||||||
|
|
||||||
//handle only EntityRepository#findOneBy
|
//handle only EntityRepository#findOneBy
|
||||||
$timestamp = $this->timestampRegion->get($this->timestampKey);
|
|
||||||
$query = $this->persister->getSelectSQL($criteria, null, null, $limit, null, $orderBy);
|
$query = $this->persister->getSelectSQL($criteria, null, null, $limit, null, $orderBy);
|
||||||
$hash = $this->getHash($query, $criteria, null, null, null, $timestamp ? $timestamp->time : null);
|
$hash = $this->getHash($query, $criteria, null, null, null);
|
||||||
$rsm = $this->getResultSetMapping();
|
$rsm = $this->getResultSetMapping();
|
||||||
$querykey = new QueryCacheKey($hash, 0, Cache::MODE_NORMAL);
|
$queryKey = new QueryCacheKey($hash, 0, Cache::MODE_NORMAL, $this->timestampKey);
|
||||||
$queryCache = $this->cache->getQueryCache($this->regionName);
|
$queryCache = $this->cache->getQueryCache($this->regionName);
|
||||||
$result = $queryCache->get($querykey, $rsm);
|
$result = $queryCache->get($queryKey, $rsm);
|
||||||
|
|
||||||
if ($result !== null) {
|
if ($result !== null) {
|
||||||
if ($this->cacheLogger) {
|
if ($this->cacheLogger) {
|
||||||
$this->cacheLogger->queryCacheHit($this->regionName, $querykey);
|
$this->cacheLogger->queryCacheHit($this->regionName, $queryKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $result[0];
|
return $result[0];
|
||||||
@ -388,15 +386,15 @@ abstract class AbstractEntityPersister implements CachedEntityPersister
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
$cached = $queryCache->put($querykey, $rsm, array($result));
|
$cached = $queryCache->put($queryKey, $rsm, array($result));
|
||||||
|
|
||||||
if ($this->cacheLogger) {
|
if ($this->cacheLogger) {
|
||||||
if ($result) {
|
if ($result) {
|
||||||
$this->cacheLogger->queryCacheMiss($this->regionName, $querykey);
|
$this->cacheLogger->queryCacheMiss($this->regionName, $queryKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($cached) {
|
if ($cached) {
|
||||||
$this->cacheLogger->queryCachePut($this->regionName, $querykey);
|
$this->cacheLogger->queryCachePut($this->regionName, $queryKey);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -408,32 +406,31 @@ abstract class AbstractEntityPersister implements CachedEntityPersister
|
|||||||
*/
|
*/
|
||||||
public function loadAll(array $criteria = array(), array $orderBy = null, $limit = null, $offset = null)
|
public function loadAll(array $criteria = array(), array $orderBy = null, $limit = null, $offset = null)
|
||||||
{
|
{
|
||||||
$timestamp = $this->timestampRegion->get($this->timestampKey);
|
|
||||||
$query = $this->persister->getSelectSQL($criteria, null, null, $limit, $offset, $orderBy);
|
$query = $this->persister->getSelectSQL($criteria, null, null, $limit, $offset, $orderBy);
|
||||||
$hash = $this->getHash($query, $criteria, null, null, null, $timestamp ? $timestamp->time : null);
|
$hash = $this->getHash($query, $criteria, null, null, null);
|
||||||
$rsm = $this->getResultSetMapping();
|
$rsm = $this->getResultSetMapping();
|
||||||
$querykey = new QueryCacheKey($hash, 0, Cache::MODE_NORMAL);
|
$queryKey = new QueryCacheKey($hash, 0, Cache::MODE_NORMAL, $this->timestampKey);
|
||||||
$queryCache = $this->cache->getQueryCache($this->regionName);
|
$queryCache = $this->cache->getQueryCache($this->regionName);
|
||||||
$result = $queryCache->get($querykey, $rsm);
|
$result = $queryCache->get($queryKey, $rsm);
|
||||||
|
|
||||||
if ($result !== null) {
|
if ($result !== null) {
|
||||||
if ($this->cacheLogger) {
|
if ($this->cacheLogger) {
|
||||||
$this->cacheLogger->queryCacheHit($this->regionName, $querykey);
|
$this->cacheLogger->queryCacheHit($this->regionName, $queryKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
$result = $this->persister->loadAll($criteria, $orderBy, $limit, $offset);
|
$result = $this->persister->loadAll($criteria, $orderBy, $limit, $offset);
|
||||||
$cached = $queryCache->put($querykey, $rsm, $result);
|
$cached = $queryCache->put($queryKey, $rsm, $result);
|
||||||
|
|
||||||
if ($this->cacheLogger) {
|
if ($this->cacheLogger) {
|
||||||
if ($result) {
|
if ($result) {
|
||||||
$this->cacheLogger->queryCacheMiss($this->regionName, $querykey);
|
$this->cacheLogger->queryCacheMiss($this->regionName, $queryKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($cached) {
|
if ($cached) {
|
||||||
$this->cacheLogger->queryCachePut($this->regionName, $querykey);
|
$this->cacheLogger->queryCachePut($this->regionName, $queryKey);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -511,31 +508,30 @@ abstract class AbstractEntityPersister implements CachedEntityPersister
|
|||||||
$limit = $criteria->getMaxResults();
|
$limit = $criteria->getMaxResults();
|
||||||
$offset = $criteria->getFirstResult();
|
$offset = $criteria->getFirstResult();
|
||||||
$query = $this->persister->getSelectSQL($criteria);
|
$query = $this->persister->getSelectSQL($criteria);
|
||||||
$timestamp = $this->timestampRegion->get($this->timestampKey);
|
$hash = $this->getHash($query, $criteria, $orderBy, $limit, $offset);
|
||||||
$hash = $this->getHash($query, $criteria, $orderBy, $limit, $offset, $timestamp ? $timestamp->time : null);
|
|
||||||
$rsm = $this->getResultSetMapping();
|
$rsm = $this->getResultSetMapping();
|
||||||
$querykey = new QueryCacheKey($hash, 0, Cache::MODE_NORMAL);
|
$queryKey = new QueryCacheKey($hash, 0, Cache::MODE_NORMAL, $this->timestampKey);
|
||||||
$queryCache = $this->cache->getQueryCache($this->regionName);
|
$queryCache = $this->cache->getQueryCache($this->regionName);
|
||||||
$cacheResult = $queryCache->get($querykey, $rsm);
|
$cacheResult = $queryCache->get($queryKey, $rsm);
|
||||||
|
|
||||||
if ($cacheResult !== null) {
|
if ($cacheResult !== null) {
|
||||||
if ($this->cacheLogger) {
|
if ($this->cacheLogger) {
|
||||||
$this->cacheLogger->queryCacheHit($this->regionName, $querykey);
|
$this->cacheLogger->queryCacheHit($this->regionName, $queryKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $cacheResult;
|
return $cacheResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
$result = $this->persister->loadCriteria($criteria);
|
$result = $this->persister->loadCriteria($criteria);
|
||||||
$cached = $queryCache->put($querykey, $rsm, $result);
|
$cached = $queryCache->put($queryKey, $rsm, $result);
|
||||||
|
|
||||||
if ($this->cacheLogger) {
|
if ($this->cacheLogger) {
|
||||||
if ($result) {
|
if ($result) {
|
||||||
$this->cacheLogger->queryCacheMiss($this->regionName, $querykey);
|
$this->cacheLogger->queryCacheMiss($this->regionName, $queryKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($cached) {
|
if ($cached) {
|
||||||
$this->cacheLogger->queryCachePut($this->regionName, $querykey);
|
$this->cacheLogger->queryCachePut($this->regionName, $queryKey);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,18 +38,18 @@ class QueryCacheEntry implements CacheEntry
|
|||||||
/**
|
/**
|
||||||
* READ-ONLY: Public only for performance reasons, it should be considered immutable.
|
* READ-ONLY: Public only for performance reasons, it should be considered immutable.
|
||||||
*
|
*
|
||||||
* @var integer Time creation of this cache entry
|
* @var float Time creation of this cache entry
|
||||||
*/
|
*/
|
||||||
public $time;
|
public $time;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param array $result
|
* @param array $result
|
||||||
* @param integer $time
|
* @param float $time
|
||||||
*/
|
*/
|
||||||
public function __construct($result, $time = null)
|
public function __construct($result, $time = null)
|
||||||
{
|
{
|
||||||
$this->result = $result;
|
$this->result = $result;
|
||||||
$this->time = $time ?: time();
|
$this->time = $time ?: microtime(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -44,15 +44,28 @@ class QueryCacheKey extends CacheKey
|
|||||||
*/
|
*/
|
||||||
public $cacheMode;
|
public $cacheMode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* READ-ONLY: Public only for performance reasons, it should be considered immutable.
|
||||||
|
*
|
||||||
|
* @var TimestampCacheKey|null
|
||||||
|
*/
|
||||||
|
public $timestampKey;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $hash Result cache id
|
* @param string $hash Result cache id
|
||||||
* @param integer $lifetime Query lifetime
|
* @param integer $lifetime Query lifetime
|
||||||
* @param integer $cacheMode Query cache mode
|
* @param int $cacheMode Query cache mode
|
||||||
|
* @param TimestampCacheKey|null $timestampKey
|
||||||
*/
|
*/
|
||||||
public function __construct($hash, $lifetime = 0, $cacheMode = Cache::MODE_NORMAL)
|
public function __construct(
|
||||||
{
|
$hash,
|
||||||
|
$lifetime = 0,
|
||||||
|
$cacheMode = Cache::MODE_NORMAL,
|
||||||
|
TimestampCacheKey $timestampKey = null
|
||||||
|
) {
|
||||||
$this->hash = $hash;
|
$this->hash = $hash;
|
||||||
$this->lifetime = $lifetime;
|
$this->lifetime = $lifetime;
|
||||||
$this->cacheMode = $cacheMode;
|
$this->cacheMode = $cacheMode;
|
||||||
|
$this->timestampKey = $timestampKey;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,15 +26,49 @@ namespace Doctrine\ORM\Cache;
|
|||||||
*/
|
*/
|
||||||
class TimestampQueryCacheValidator implements QueryCacheValidator
|
class TimestampQueryCacheValidator implements QueryCacheValidator
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @var TimestampRegion
|
||||||
|
*/
|
||||||
|
private $timestampRegion;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param TimestampRegion $timestampRegion
|
||||||
|
*/
|
||||||
|
public function __construct(TimestampRegion $timestampRegion)
|
||||||
|
{
|
||||||
|
$this->timestampRegion = $timestampRegion;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
public function isValid(QueryCacheKey $key, QueryCacheEntry $entry)
|
public function isValid(QueryCacheKey $key, QueryCacheEntry $entry)
|
||||||
{
|
{
|
||||||
|
if ($this->regionUpdated($key, $entry)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if ($key->lifetime == 0) {
|
if ($key->lifetime == 0) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ($entry->time + $key->lifetime) > time();
|
return ($entry->time + $key->lifetime) > microtime(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param QueryCacheKey $key
|
||||||
|
* @param QueryCacheEntry $entry
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
private function regionUpdated(QueryCacheKey $key, QueryCacheEntry $entry)
|
||||||
|
{
|
||||||
|
if ($key->timestampKey === null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$timestamp = $this->timestampRegion->get($key->timestampKey);
|
||||||
|
|
||||||
|
return $timestamp && $timestamp->time > $entry->time;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,7 @@ namespace Doctrine\ORM;
|
|||||||
use Exception;
|
use Exception;
|
||||||
use Doctrine\Common\EventManager;
|
use Doctrine\Common\EventManager;
|
||||||
use Doctrine\DBAL\Connection;
|
use Doctrine\DBAL\Connection;
|
||||||
|
use Doctrine\DBAL\DriverManager;
|
||||||
use Doctrine\DBAL\LockMode;
|
use Doctrine\DBAL\LockMode;
|
||||||
use Doctrine\ORM\Query\ResultSetMapping;
|
use Doctrine\ORM\Query\ResultSetMapping;
|
||||||
use Doctrine\ORM\Proxy\ProxyFactory;
|
use Doctrine\ORM\Proxy\ProxyFactory;
|
||||||
@ -289,7 +290,7 @@ use Doctrine\Common\Util\ClassUtils;
|
|||||||
$query = new Query($this);
|
$query = new Query($this);
|
||||||
|
|
||||||
if ( ! empty($dql)) {
|
if ( ! empty($dql)) {
|
||||||
$query->setDql($dql);
|
$query->setDQL($dql);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $query;
|
return $query;
|
||||||
@ -310,7 +311,7 @@ use Doctrine\Common\Util\ClassUtils;
|
|||||||
{
|
{
|
||||||
$query = new NativeQuery($this);
|
$query = new NativeQuery($this);
|
||||||
|
|
||||||
$query->setSql($sql);
|
$query->setSQL($sql);
|
||||||
$query->setResultSetMapping($rsm);
|
$query->setResultSetMapping($rsm);
|
||||||
|
|
||||||
return $query;
|
return $query;
|
||||||
@ -820,7 +821,7 @@ use Doctrine\Common\Util\ClassUtils;
|
|||||||
/**
|
/**
|
||||||
* Factory method to create EntityManager instances.
|
* Factory method to create EntityManager instances.
|
||||||
*
|
*
|
||||||
* @param mixed $conn An array with the connection parameters or an existing Connection instance.
|
* @param array|Connection $connection An array with the connection parameters or an existing Connection instance.
|
||||||
* @param Configuration $config The Configuration instance to use.
|
* @param Configuration $config The Configuration instance to use.
|
||||||
* @param EventManager $eventManager The EventManager instance to use.
|
* @param EventManager $eventManager The EventManager instance to use.
|
||||||
*
|
*
|
||||||
@ -829,30 +830,44 @@ use Doctrine\Common\Util\ClassUtils;
|
|||||||
* @throws \InvalidArgumentException
|
* @throws \InvalidArgumentException
|
||||||
* @throws ORMException
|
* @throws ORMException
|
||||||
*/
|
*/
|
||||||
public static function create($conn, Configuration $config, EventManager $eventManager = null)
|
public static function create($connection, Configuration $config, EventManager $eventManager = null)
|
||||||
{
|
{
|
||||||
if ( ! $config->getMetadataDriverImpl()) {
|
if ( ! $config->getMetadataDriverImpl()) {
|
||||||
throw ORMException::missingMappingDriverImpl();
|
throw ORMException::missingMappingDriverImpl();
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (true) {
|
$connection = static::createConnection($connection, $config, $eventManager);
|
||||||
case (is_array($conn)):
|
|
||||||
$conn = \Doctrine\DBAL\DriverManager::getConnection(
|
|
||||||
$conn, $config, ($eventManager ?: new EventManager())
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ($conn instanceof Connection):
|
return new EntityManager($connection, $config, $connection->getEventManager());
|
||||||
if ($eventManager !== null && $conn->getEventManager() !== $eventManager) {
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Factory method to create Connection instances.
|
||||||
|
*
|
||||||
|
* @param array|Connection $connection An array with the connection parameters or an existing Connection instance.
|
||||||
|
* @param Configuration $config The Configuration instance to use.
|
||||||
|
* @param EventManager $eventManager The EventManager instance to use.
|
||||||
|
*
|
||||||
|
* @return Connection
|
||||||
|
*
|
||||||
|
* @throws \InvalidArgumentException
|
||||||
|
* @throws ORMException
|
||||||
|
*/
|
||||||
|
protected static function createConnection($connection, Configuration $config, EventManager $eventManager = null)
|
||||||
|
{
|
||||||
|
if (is_array($connection)) {
|
||||||
|
return DriverManager::getConnection($connection, $config, $eventManager ?: new EventManager());
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ! $connection instanceof Connection) {
|
||||||
|
throw new \InvalidArgumentException("Invalid argument: " . $connection);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($eventManager !== null && $connection->getEventManager() !== $eventManager) {
|
||||||
throw ORMException::mismatchedEventManager();
|
throw ORMException::mismatchedEventManager();
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
return $connection;
|
||||||
throw new \InvalidArgumentException("Invalid argument: " . $conn);
|
|
||||||
}
|
|
||||||
|
|
||||||
return new EntityManager($conn, $config, $conn->getEventManager());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -7,9 +7,9 @@
|
|||||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION); HOWEVER CAUSED AND ON ANY
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE); ARISING IN ANY WAY OUT OF THE USE
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* This software consists of voluntary contributions made by many individuals
|
* This software consists of voluntary contributions made by many individuals
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
|
|
||||||
namespace Doctrine\ORM;
|
namespace Doctrine\ORM;
|
||||||
|
|
||||||
use Doctrine\ORM\EntityManagerInterface;
|
use Doctrine\Common\Util\Inflector;
|
||||||
use Doctrine\ORM\Query\ResultSetMappingBuilder;
|
use Doctrine\ORM\Query\ResultSetMappingBuilder;
|
||||||
use Doctrine\Common\Persistence\ObjectRepository;
|
use Doctrine\Common\Persistence\ObjectRepository;
|
||||||
use Doctrine\Common\Collections\Selectable;
|
use Doctrine\Common\Collections\Selectable;
|
||||||
@ -197,66 +197,50 @@ class EntityRepository implements ObjectRepository, Selectable
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds support for magic finders.
|
* Counts entities by a set of criteria.
|
||||||
|
*
|
||||||
|
* @todo Add this method to `ObjectRepository` interface in the next major release
|
||||||
|
*
|
||||||
|
* @param array $criteria
|
||||||
|
*
|
||||||
|
* @return int The cardinality of the objects that match the given criteria.
|
||||||
|
*/
|
||||||
|
public function count(array $criteria)
|
||||||
|
{
|
||||||
|
return $this->_em->getUnitOfWork()->getEntityPersister($this->_entityName)->count($criteria);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds support for magic method calls.
|
||||||
*
|
*
|
||||||
* @param string $method
|
* @param string $method
|
||||||
* @param array $arguments
|
* @param array $arguments
|
||||||
*
|
*
|
||||||
* @return array|object The found entity/entities.
|
* @return mixed The returned value from the resolved method.
|
||||||
*
|
*
|
||||||
* @throws ORMException
|
* @throws ORMException
|
||||||
* @throws \BadMethodCallException If the method called is an invalid find* method
|
* @throws \BadMethodCallException If the method called is invalid
|
||||||
* or no find* method at all and therefore an invalid
|
|
||||||
* method call.
|
|
||||||
*/
|
*/
|
||||||
public function __call($method, $arguments)
|
public function __call($method, $arguments)
|
||||||
{
|
{
|
||||||
switch (true) {
|
if (0 === strpos($method, 'findBy')) {
|
||||||
case (0 === strpos($method, 'findBy')):
|
return $this->resolveMagicCall('findBy', substr($method, 6), $arguments);
|
||||||
$by = substr($method, 6);
|
}
|
||||||
$method = 'findBy';
|
|
||||||
break;
|
|
||||||
|
|
||||||
case (0 === strpos($method, 'findOneBy')):
|
if (0 === strpos($method, 'findOneBy')) {
|
||||||
$by = substr($method, 9);
|
return $this->resolveMagicCall('findOneBy', substr($method, 9), $arguments);
|
||||||
$method = 'findOneBy';
|
}
|
||||||
break;
|
|
||||||
|
if (0 === strpos($method, 'countBy')) {
|
||||||
|
return $this->resolveMagicCall('count', substr($method, 7), $arguments);
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
|
||||||
throw new \BadMethodCallException(
|
throw new \BadMethodCallException(
|
||||||
"Undefined method '$method'. The method name must start with ".
|
"Undefined method '$method'. The method name must start with ".
|
||||||
"either findBy or findOneBy!"
|
"either findBy, findOneBy or countBy!"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (empty($arguments)) {
|
|
||||||
throw ORMException::findByRequiresParameter($method . $by);
|
|
||||||
}
|
|
||||||
|
|
||||||
$fieldName = lcfirst(\Doctrine\Common\Util\Inflector::classify($by));
|
|
||||||
|
|
||||||
if ($this->_class->hasField($fieldName) || $this->_class->hasAssociation($fieldName)) {
|
|
||||||
switch (count($arguments)) {
|
|
||||||
case 1:
|
|
||||||
return $this->$method(array($fieldName => $arguments[0]));
|
|
||||||
|
|
||||||
case 2:
|
|
||||||
return $this->$method(array($fieldName => $arguments[0]), $arguments[1]);
|
|
||||||
|
|
||||||
case 3:
|
|
||||||
return $this->$method(array($fieldName => $arguments[0]), $arguments[1], $arguments[2]);
|
|
||||||
|
|
||||||
case 4:
|
|
||||||
return $this->$method(array($fieldName => $arguments[0]), $arguments[1], $arguments[2], $arguments[3]);
|
|
||||||
|
|
||||||
default:
|
|
||||||
// Do nothing
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
throw ORMException::invalidFindByCall($this->_entityName, $fieldName, $method.$by);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
@ -303,4 +287,30 @@ class EntityRepository implements ObjectRepository, Selectable
|
|||||||
|
|
||||||
return new LazyCriteriaCollection($persister, $criteria);
|
return new LazyCriteriaCollection($persister, $criteria);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resolves a magic method call to the proper existent method at `EntityRepository`.
|
||||||
|
*
|
||||||
|
* @param string $method The method to call
|
||||||
|
* @param string $by The property name used as condition
|
||||||
|
* @param array $arguments The arguments to pass at method call
|
||||||
|
*
|
||||||
|
* @throws ORMException If the method called is invalid or the requested field/association does not exist
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
private function resolveMagicCall($method, $by, array $arguments)
|
||||||
|
{
|
||||||
|
if (! $arguments) {
|
||||||
|
throw ORMException::findByRequiresParameter($method . $by);
|
||||||
|
}
|
||||||
|
|
||||||
|
$fieldName = lcfirst(Inflector::classify($by));
|
||||||
|
|
||||||
|
if (! ($this->_class->hasField($fieldName) || $this->_class->hasAssociation($fieldName))) {
|
||||||
|
throw ORMException::invalidMagicCall($this->_entityName, $fieldName, $method . $by);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->$method([$fieldName => $arguments[0]], ...array_slice($arguments, 1));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
* This software consists of voluntary contributions made by many individuals
|
* This software consists of voluntary contributions made by many individuals
|
||||||
* and is licensed under the MIT license. For more information, see
|
* and is licensed under the MIT license. For more information, see
|
||||||
* <http://www.doctrine-project.org>.
|
* <http://www.doctrine-project.org>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace Doctrine\ORM\Event;
|
namespace Doctrine\ORM\Event;
|
||||||
|
|
||||||
|
@ -24,9 +24,6 @@ use PDO;
|
|||||||
use Doctrine\ORM\Mapping\ClassMetadata;
|
use Doctrine\ORM\Mapping\ClassMetadata;
|
||||||
use Doctrine\ORM\PersistentCollection;
|
use Doctrine\ORM\PersistentCollection;
|
||||||
use Doctrine\ORM\Query;
|
use Doctrine\ORM\Query;
|
||||||
use Doctrine\ORM\Events;
|
|
||||||
use Doctrine\ORM\Event\LifecycleEventArgs;
|
|
||||||
use Doctrine\ORM\Event\PostLoadEventDispatcher;
|
|
||||||
use Doctrine\Common\Collections\ArrayCollection;
|
use Doctrine\Common\Collections\ArrayCollection;
|
||||||
use Doctrine\ORM\Proxy\Proxy;
|
use Doctrine\ORM\Proxy\Proxy;
|
||||||
|
|
||||||
@ -332,6 +329,9 @@ class ObjectHydrator extends AbstractHydrator
|
|||||||
// Split the row data into chunks of class data.
|
// Split the row data into chunks of class data.
|
||||||
$rowData = $this->gatherRowData($row, $id, $nonemptyComponents);
|
$rowData = $this->gatherRowData($row, $id, $nonemptyComponents);
|
||||||
|
|
||||||
|
// reset result pointers for each data row
|
||||||
|
$this->resultPointers = [];
|
||||||
|
|
||||||
// Hydrate the data chunks
|
// Hydrate the data chunks
|
||||||
foreach ($rowData['data'] as $dqlAlias => $data) {
|
foreach ($rowData['data'] as $dqlAlias => $data) {
|
||||||
$entityName = $this->_rsm->aliasMap[$dqlAlias];
|
$entityName = $this->_rsm->aliasMap[$dqlAlias];
|
||||||
@ -586,10 +586,7 @@ class ObjectHydrator extends AbstractHydrator
|
|||||||
parent::onClear($eventArgs);
|
parent::onClear($eventArgs);
|
||||||
|
|
||||||
$aliases = array_keys($this->identifierMap);
|
$aliases = array_keys($this->identifierMap);
|
||||||
$this->identifierMap = array();
|
|
||||||
|
|
||||||
foreach ($aliases as $alias) {
|
$this->identifierMap = array_fill_keys($aliases, []);
|
||||||
$this->identifierMap[$alias] = array();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,6 @@
|
|||||||
namespace Doctrine\ORM\Internal\Hydration;
|
namespace Doctrine\ORM\Internal\Hydration;
|
||||||
|
|
||||||
use PDO;
|
use PDO;
|
||||||
use Doctrine\DBAL\Types\Type;
|
|
||||||
use Doctrine\ORM\Mapping\ClassMetadata;
|
use Doctrine\ORM\Mapping\ClassMetadata;
|
||||||
use Doctrine\ORM\Query;
|
use Doctrine\ORM\Query;
|
||||||
|
|
||||||
@ -122,6 +121,9 @@ class SimpleObjectHydrator extends AbstractHydrator
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check if value is null before conversion (because some types convert null to something else)
|
||||||
|
$valueIsNull = null === $value;
|
||||||
|
|
||||||
// Convert field to a valid PHP value
|
// Convert field to a valid PHP value
|
||||||
if (isset($cacheKeyInfo['type'])) {
|
if (isset($cacheKeyInfo['type'])) {
|
||||||
$type = $cacheKeyInfo['type'];
|
$type = $cacheKeyInfo['type'];
|
||||||
@ -131,7 +133,7 @@ class SimpleObjectHydrator extends AbstractHydrator
|
|||||||
$fieldName = $cacheKeyInfo['fieldName'];
|
$fieldName = $cacheKeyInfo['fieldName'];
|
||||||
|
|
||||||
// Prevent overwrite in case of inherit classes using same property name (See AbstractHydrator)
|
// Prevent overwrite in case of inherit classes using same property name (See AbstractHydrator)
|
||||||
if ( ! isset($data[$fieldName]) || $value !== null) {
|
if ( ! isset($data[$fieldName]) || ! $valueIsNull) {
|
||||||
$data[$fieldName] = $value;
|
$data[$fieldName] = $value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -941,8 +941,13 @@ class ClassMetadataInfo implements ClassMetadata
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
$parentReflFields[$property] = $reflService->getAccessibleProperty($this->name, $property);
|
$fieldRefl = $reflService->getAccessibleProperty(
|
||||||
$this->reflFields[$property] = $reflService->getAccessibleProperty($this->name, $property);
|
isset($embeddedClass['declared']) ? $embeddedClass['declared'] : $this->name,
|
||||||
|
$property
|
||||||
|
);
|
||||||
|
|
||||||
|
$parentReflFields[$property] = $fieldRefl;
|
||||||
|
$this->reflFields[$property] = $fieldRefl;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($this->fieldMappings as $field => $mapping) {
|
foreach ($this->fieldMappings as $field => $mapping) {
|
||||||
@ -1460,8 +1465,7 @@ class ClassMetadataInfo implements ClassMetadata
|
|||||||
|
|
||||||
$mapping['isOwningSide'] = true; // assume owning side until we hit mappedBy
|
$mapping['isOwningSide'] = true; // assume owning side until we hit mappedBy
|
||||||
|
|
||||||
// unset optional indexBy attribute if its empty
|
if (empty($mapping['indexBy'])) {
|
||||||
if ( ! isset($mapping['indexBy']) || !$mapping['indexBy']) {
|
|
||||||
unset($mapping['indexBy']);
|
unset($mapping['indexBy']);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1539,13 +1543,12 @@ class ClassMetadataInfo implements ClassMetadata
|
|||||||
// Cascades
|
// Cascades
|
||||||
$cascades = isset($mapping['cascade']) ? array_map('strtolower', $mapping['cascade']) : array();
|
$cascades = isset($mapping['cascade']) ? array_map('strtolower', $mapping['cascade']) : array();
|
||||||
|
|
||||||
|
$allCascades = array('remove', 'persist', 'refresh', 'merge', 'detach');
|
||||||
if (in_array('all', $cascades)) {
|
if (in_array('all', $cascades)) {
|
||||||
$cascades = array('remove', 'persist', 'refresh', 'merge', 'detach');
|
$cascades = $allCascades;
|
||||||
}
|
} elseif (count($cascades) !== count(array_intersect($cascades, $allCascades))) {
|
||||||
|
|
||||||
if (count($cascades) !== count(array_intersect($cascades, array('remove', 'persist', 'refresh', 'merge', 'detach')))) {
|
|
||||||
throw MappingException::invalidCascadeOption(
|
throw MappingException::invalidCascadeOption(
|
||||||
array_diff($cascades, array_intersect($cascades, array('remove', 'persist', 'refresh', 'merge', 'detach'))),
|
array_diff($cascades, $allCascades),
|
||||||
$this->name,
|
$this->name,
|
||||||
$mapping['fieldName']
|
$mapping['fieldName']
|
||||||
);
|
);
|
||||||
@ -1580,7 +1583,7 @@ class ClassMetadataInfo implements ClassMetadata
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ($mapping['isOwningSide']) {
|
if ($mapping['isOwningSide']) {
|
||||||
if ( ! isset($mapping['joinColumns']) || ! $mapping['joinColumns']) {
|
if (empty($mapping['joinColumns'])) {
|
||||||
// Apply default join column
|
// Apply default join column
|
||||||
$mapping['joinColumns'] = array(
|
$mapping['joinColumns'] = array(
|
||||||
array(
|
array(
|
||||||
@ -1594,8 +1597,8 @@ class ClassMetadataInfo implements ClassMetadata
|
|||||||
|
|
||||||
foreach ($mapping['joinColumns'] as &$joinColumn) {
|
foreach ($mapping['joinColumns'] as &$joinColumn) {
|
||||||
if ($mapping['type'] === self::ONE_TO_ONE && ! $this->isInheritanceTypeSingleTable()) {
|
if ($mapping['type'] === self::ONE_TO_ONE && ! $this->isInheritanceTypeSingleTable()) {
|
||||||
if (count($mapping['joinColumns']) == 1) {
|
if (count($mapping['joinColumns']) === 1) {
|
||||||
if ( ! isset($mapping['id']) || ! $mapping['id']) {
|
if (empty($mapping['id'])) {
|
||||||
$joinColumn['unique'] = true;
|
$joinColumn['unique'] = true;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -1640,8 +1643,8 @@ class ClassMetadataInfo implements ClassMetadata
|
|||||||
$mapping['targetToSourceKeyColumns'] = array_flip($mapping['sourceToTargetKeyColumns']);
|
$mapping['targetToSourceKeyColumns'] = array_flip($mapping['sourceToTargetKeyColumns']);
|
||||||
}
|
}
|
||||||
|
|
||||||
$mapping['orphanRemoval'] = isset($mapping['orphanRemoval']) ? (bool) $mapping['orphanRemoval'] : false;
|
$mapping['orphanRemoval'] = isset($mapping['orphanRemoval']) && $mapping['orphanRemoval'];
|
||||||
$mapping['isCascadeRemove'] = $mapping['orphanRemoval'] ? true : $mapping['isCascadeRemove'];
|
$mapping['isCascadeRemove'] = $mapping['orphanRemoval'] || $mapping['isCascadeRemove'];
|
||||||
|
|
||||||
if ($mapping['orphanRemoval']) {
|
if ($mapping['orphanRemoval']) {
|
||||||
unset($mapping['unique']);
|
unset($mapping['unique']);
|
||||||
@ -1673,14 +1676,10 @@ class ClassMetadataInfo implements ClassMetadata
|
|||||||
throw MappingException::oneToManyRequiresMappedBy($mapping['fieldName']);
|
throw MappingException::oneToManyRequiresMappedBy($mapping['fieldName']);
|
||||||
}
|
}
|
||||||
|
|
||||||
$mapping['orphanRemoval'] = isset($mapping['orphanRemoval']) ? (bool) $mapping['orphanRemoval'] : false;
|
$mapping['orphanRemoval'] = isset($mapping['orphanRemoval']) && $mapping['orphanRemoval'];
|
||||||
$mapping['isCascadeRemove'] = $mapping['orphanRemoval'] ? true : $mapping['isCascadeRemove'];
|
$mapping['isCascadeRemove'] = $mapping['orphanRemoval'] || $mapping['isCascadeRemove'];
|
||||||
|
|
||||||
if (isset($mapping['orderBy'])) {
|
$this->assertMappingOrderBy($mapping);
|
||||||
if ( ! is_array($mapping['orderBy'])) {
|
|
||||||
throw new InvalidArgumentException("'orderBy' is expected to be an array, not ".gettype($mapping['orderBy']));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $mapping;
|
return $mapping;
|
||||||
}
|
}
|
||||||
@ -1784,13 +1783,9 @@ class ClassMetadataInfo implements ClassMetadata
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$mapping['orphanRemoval'] = isset($mapping['orphanRemoval']) ? (bool) $mapping['orphanRemoval'] : false;
|
$mapping['orphanRemoval'] = isset($mapping['orphanRemoval']) && $mapping['orphanRemoval'];
|
||||||
|
|
||||||
if (isset($mapping['orderBy'])) {
|
$this->assertMappingOrderBy($mapping);
|
||||||
if ( ! is_array($mapping['orderBy'])) {
|
|
||||||
throw new InvalidArgumentException("'orderBy' is expected to be an array, not ".gettype($mapping['orderBy']));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $mapping;
|
return $mapping;
|
||||||
}
|
}
|
||||||
@ -2208,11 +2203,11 @@ class ClassMetadataInfo implements ClassMetadata
|
|||||||
$overrideMapping['id'] = $mapping['id'];
|
$overrideMapping['id'] = $mapping['id'];
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ! isset($overrideMapping['type']) || $overrideMapping['type'] === null) {
|
if ( ! isset($overrideMapping['type'])) {
|
||||||
$overrideMapping['type'] = $mapping['type'];
|
$overrideMapping['type'] = $mapping['type'];
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ! isset($overrideMapping['fieldName']) || $overrideMapping['fieldName'] === null) {
|
if ( ! isset($overrideMapping['fieldName'])) {
|
||||||
$overrideMapping['fieldName'] = $mapping['fieldName'];
|
$overrideMapping['fieldName'] = $mapping['fieldName'];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2948,7 +2943,8 @@ class ClassMetadataInfo implements ClassMetadata
|
|||||||
{
|
{
|
||||||
if (isset($this->fieldNames[$columnName])) {
|
if (isset($this->fieldNames[$columnName])) {
|
||||||
return $this->fieldNames[$columnName];
|
return $this->fieldNames[$columnName];
|
||||||
} else {
|
}
|
||||||
|
|
||||||
foreach ($this->associationMappings as $assocName => $mapping) {
|
foreach ($this->associationMappings as $assocName => $mapping) {
|
||||||
if ($this->isAssociationWithSingleJoinColumn($assocName) &&
|
if ($this->isAssociationWithSingleJoinColumn($assocName) &&
|
||||||
$this->associationMappings[$assocName]['joinColumns'][0]['name'] == $columnName) {
|
$this->associationMappings[$assocName]['joinColumns'][0]['name'] == $columnName) {
|
||||||
@ -2959,7 +2955,6 @@ class ClassMetadataInfo implements ClassMetadata
|
|||||||
|
|
||||||
throw MappingException::noFieldNameFoundForColumn($this->name, $columnName);
|
throw MappingException::noFieldNameFoundForColumn($this->name, $columnName);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the ID generator used to generate IDs for instances of this class.
|
* Sets the ID generator used to generate IDs for instances of this class.
|
||||||
@ -3385,4 +3380,14 @@ class ClassMetadataInfo implements ClassMetadata
|
|||||||
|
|
||||||
return $sequencePrefix;
|
return $sequencePrefix;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array $mapping
|
||||||
|
*/
|
||||||
|
private function assertMappingOrderBy(array $mapping)
|
||||||
|
{
|
||||||
|
if (isset($mapping['orderBy']) && !is_array($mapping['orderBy'])) {
|
||||||
|
throw new InvalidArgumentException("'orderBy' is expected to be an array, not " . gettype($mapping['orderBy']));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
* This software consists of voluntary contributions made by many individuals
|
* This software consists of voluntary contributions made by many individuals
|
||||||
* and is licensed under the MIT license. For more information, see
|
* and is licensed under the MIT license. For more information, see
|
||||||
* <http://www.doctrine-project.org>.
|
* <http://www.doctrine-project.org>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace Doctrine\ORM\Mapping\Driver;
|
namespace Doctrine\ORM\Mapping\Driver;
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
* This software consists of voluntary contributions made by many individuals
|
* This software consists of voluntary contributions made by many individuals
|
||||||
* and is licensed under the MIT license. For more information, see
|
* and is licensed under the MIT license. For more information, see
|
||||||
* <http://www.doctrine-project.org>.
|
* <http://www.doctrine-project.org>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace Doctrine\ORM\Mapping\Driver;
|
namespace Doctrine\ORM\Mapping\Driver;
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
*
|
*
|
||||||
* This software consists of voluntary contributions made by many individuals
|
* This software consists of voluntary contributions made by many individuals
|
||||||
* and is licensed under the MIT license. For more information, see
|
* and is licensed under the MIT license. For more information, see
|
||||||
* <http://www.phpdoctrine.org>.
|
* <http://www.doctrine-project.org>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace Doctrine\ORM\Mapping;
|
namespace Doctrine\ORM\Mapping;
|
||||||
|
@ -187,6 +187,21 @@ class ORMException extends Exception
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $entityName
|
||||||
|
* @param string $fieldName
|
||||||
|
* @param string $method
|
||||||
|
*
|
||||||
|
* @return ORMException
|
||||||
|
*/
|
||||||
|
public static function invalidMagicCall($entityName, $fieldName, $method)
|
||||||
|
{
|
||||||
|
return new self(
|
||||||
|
"Entity '".$entityName."' has no field '".$fieldName."'. ".
|
||||||
|
"You can therefore not call '".$method."' on the entities' repository"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $entityName
|
* @param string $entityName
|
||||||
* @param string $associationFieldName
|
* @param string $associationFieldName
|
||||||
|
@ -21,7 +21,6 @@ namespace Doctrine\ORM\Persisters\Collection;
|
|||||||
|
|
||||||
use Doctrine\Common\Collections\Criteria;
|
use Doctrine\Common\Collections\Criteria;
|
||||||
use Doctrine\ORM\Mapping\ClassMetadata;
|
use Doctrine\ORM\Mapping\ClassMetadata;
|
||||||
use Doctrine\ORM\Persisters\SqlExpressionVisitor;
|
|
||||||
use Doctrine\ORM\Persisters\SqlValueVisitor;
|
use Doctrine\ORM\Persisters\SqlValueVisitor;
|
||||||
use Doctrine\ORM\PersistentCollection;
|
use Doctrine\ORM\PersistentCollection;
|
||||||
use Doctrine\ORM\Query;
|
use Doctrine\ORM\Query;
|
||||||
@ -740,7 +739,7 @@ class ManyToManyPersister extends AbstractCollectionPersister
|
|||||||
|
|
||||||
$valueVisitor->dispatch($expression);
|
$valueVisitor->dispatch($expression);
|
||||||
|
|
||||||
list($values, $types) = $valueVisitor->getParamsAndTypes();
|
list(, $types) = $valueVisitor->getParamsAndTypes();
|
||||||
|
|
||||||
return $types;
|
return $types;
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,6 @@
|
|||||||
namespace Doctrine\ORM\Persisters\Collection;
|
namespace Doctrine\ORM\Persisters\Collection;
|
||||||
|
|
||||||
use Doctrine\Common\Collections\Criteria;
|
use Doctrine\Common\Collections\Criteria;
|
||||||
use Doctrine\Common\Proxy\Proxy;
|
|
||||||
use Doctrine\DBAL\Types\Type;
|
use Doctrine\DBAL\Types\Type;
|
||||||
use Doctrine\ORM\PersistentCollection;
|
use Doctrine\ORM\PersistentCollection;
|
||||||
use Doctrine\ORM\Utility\PersisterHelper;
|
use Doctrine\ORM\Utility\PersisterHelper;
|
||||||
|
@ -822,7 +822,7 @@ class BasicEntityPersister implements EntityPersister
|
|||||||
? $this->expandCriteriaParameters($criteria)
|
? $this->expandCriteriaParameters($criteria)
|
||||||
: $this->expandParameters($criteria);
|
: $this->expandParameters($criteria);
|
||||||
|
|
||||||
return $this->conn->executeQuery($sql, $params, $types)->fetchColumn();
|
return (int) $this->conn->executeQuery($sql, $params, $types)->fetchColumn();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1442,7 +1442,7 @@ class BasicEntityPersister implements EntityPersister
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->class->generatorType != ClassMetadata::GENERATOR_TYPE_IDENTITY || $this->class->identifier[0] != $name) {
|
if (! $this->class->isIdGeneratorIdentity() || $this->class->identifier[0] != $name) {
|
||||||
$columns[] = $this->quoteStrategy->getColumnName($name, $this->class, $this->platform);
|
$columns[] = $this->quoteStrategy->getColumnName($name, $this->class, $this->platform);
|
||||||
$this->columnTypes[$name] = $this->class->fieldMappings[$name]['type'];
|
$this->columnTypes[$name] = $this->class->fieldMappings[$name]['type'];
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,6 @@
|
|||||||
namespace Doctrine\ORM\Persisters\Entity;
|
namespace Doctrine\ORM\Persisters\Entity;
|
||||||
|
|
||||||
use Doctrine\ORM\Mapping\ClassMetadata;
|
use Doctrine\ORM\Mapping\ClassMetadata;
|
||||||
use Doctrine\ORM\Query\ResultSetMapping;
|
|
||||||
|
|
||||||
use Doctrine\DBAL\LockMode;
|
use Doctrine\DBAL\LockMode;
|
||||||
use Doctrine\DBAL\Types\Type;
|
use Doctrine\DBAL\Types\Type;
|
||||||
|
@ -196,7 +196,7 @@ class ProxyFactory extends AbstractProxyFactory
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($class->getReflectionClass()->getProperties() as $property) {
|
foreach ($class->getReflectionProperties() as $property) {
|
||||||
if ( ! $class->hasField($property->name) && ! $class->hasAssociation($property->name)) {
|
if ( ! $class->hasField($property->name) && ! $class->hasAssociation($property->name)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* This software consists of voluntary contributions made by many individuals
|
* This software consists of voluntary contributions made by many individuals
|
||||||
* and is licensed under the MIT. For more information, see
|
* and is licensed under the MIT license. For more information, see
|
||||||
* <http://www.doctrine-project.org>.
|
* <http://www.doctrine-project.org>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -118,8 +118,6 @@ class MultiTableDeleteExecutor extends AbstractSqlExecutor
|
|||||||
*/
|
*/
|
||||||
public function execute(Connection $conn, array $params, array $types)
|
public function execute(Connection $conn, array $params, array $types)
|
||||||
{
|
{
|
||||||
$numDeleted = 0;
|
|
||||||
|
|
||||||
// Create temporary id table
|
// Create temporary id table
|
||||||
$conn->executeUpdate($this->_createTempTableSql);
|
$conn->executeUpdate($this->_createTempTableSql);
|
||||||
|
|
||||||
|
@ -163,8 +163,6 @@ class MultiTableUpdateExecutor extends AbstractSqlExecutor
|
|||||||
*/
|
*/
|
||||||
public function execute(Connection $conn, array $params, array $types)
|
public function execute(Connection $conn, array $params, array $types)
|
||||||
{
|
{
|
||||||
$numUpdated = 0;
|
|
||||||
|
|
||||||
// Create temporary id table
|
// Create temporary id table
|
||||||
$conn->executeUpdate($this->_createTempTableSql);
|
$conn->executeUpdate($this->_createTempTableSql);
|
||||||
|
|
||||||
|
@ -827,18 +827,14 @@ class Parser
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$foundRootEntity = false;
|
|
||||||
|
|
||||||
foreach ($this->identVariableExpressions as $dqlAlias => $expr) {
|
foreach ($this->identVariableExpressions as $dqlAlias => $expr) {
|
||||||
if (isset($this->queryComponents[$dqlAlias]) && $this->queryComponents[$dqlAlias]['parent'] === null) {
|
if (isset($this->queryComponents[$dqlAlias]) && $this->queryComponents[$dqlAlias]['parent'] === null) {
|
||||||
$foundRootEntity = true;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ! $foundRootEntity) {
|
|
||||||
$this->semanticalError('Cannot select entity through identification variables without choosing at least one root entity alias.');
|
$this->semanticalError('Cannot select entity through identification variables without choosing at least one root entity alias.');
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* QueryLanguage ::= SelectStatement | UpdateStatement | DeleteStatement
|
* QueryLanguage ::= SelectStatement | UpdateStatement | DeleteStatement
|
||||||
@ -2953,7 +2949,7 @@ class Parser
|
|||||||
/**
|
/**
|
||||||
* EntityExpression ::= SingleValuedAssociationPathExpression | SimpleEntityExpression
|
* EntityExpression ::= SingleValuedAssociationPathExpression | SimpleEntityExpression
|
||||||
*
|
*
|
||||||
* @return \Doctrine\ORM\Query\AST\SingleValuedAssociationPathExpression |
|
* @return \Doctrine\ORM\Query\AST\PathExpression |
|
||||||
* \Doctrine\ORM\Query\AST\SimpleEntityExpression
|
* \Doctrine\ORM\Query\AST\SimpleEntityExpression
|
||||||
*/
|
*/
|
||||||
public function EntityExpression()
|
public function EntityExpression()
|
||||||
|
@ -19,7 +19,6 @@
|
|||||||
|
|
||||||
namespace Doctrine\ORM\Query;
|
namespace Doctrine\ORM\Query;
|
||||||
|
|
||||||
use Doctrine\DBAL\Types\Type;
|
|
||||||
use Doctrine\ORM\EntityManagerInterface;
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
use Doctrine\ORM\Mapping\ClassMetadataInfo;
|
use Doctrine\ORM\Mapping\ClassMetadataInfo;
|
||||||
use Doctrine\ORM\Mapping\MappingException;
|
use Doctrine\ORM\Mapping\MappingException;
|
||||||
|
@ -469,14 +469,15 @@ class QueryBuilder
|
|||||||
* $qb = $em->createQueryBuilder()
|
* $qb = $em->createQueryBuilder()
|
||||||
* ->select('u')
|
* ->select('u')
|
||||||
* ->from('User', 'u')
|
* ->from('User', 'u')
|
||||||
* ->join('u.articles','a';
|
* ->join('u.articles','a');
|
||||||
*
|
*
|
||||||
* $qb->getAllAliases(); // array('u','a')
|
* $qb->getAllAliases(); // array('u','a')
|
||||||
* </code>
|
* </code>
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function getAllAliases() {
|
public function getAllAliases()
|
||||||
return array_merge($this->getRootAliases(),array_keys($this->joinRootAliases));
|
{
|
||||||
|
return array_merge($this->getRootAliases(), array_keys($this->joinRootAliases));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -117,7 +117,7 @@ class PhpExporter extends AbstractExporter
|
|||||||
$oneToOneMappingArray = array(
|
$oneToOneMappingArray = array(
|
||||||
'mappedBy' => $associationMapping['mappedBy'],
|
'mappedBy' => $associationMapping['mappedBy'],
|
||||||
'inversedBy' => $associationMapping['inversedBy'],
|
'inversedBy' => $associationMapping['inversedBy'],
|
||||||
'joinColumns' => $associationMapping['joinColumns'],
|
'joinColumns' => $associationMapping['isOwningSide'] ? $associationMapping['joinColumns'] : [],
|
||||||
'orphanRemoval' => $associationMapping['orphanRemoval'],
|
'orphanRemoval' => $associationMapping['orphanRemoval'],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -163,7 +163,7 @@ class YamlExporter extends AbstractExporter
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ($associationMapping['type'] & ClassMetadataInfo::TO_ONE) {
|
if ($associationMapping['type'] & ClassMetadataInfo::TO_ONE) {
|
||||||
$joinColumns = $associationMapping['joinColumns'];
|
$joinColumns = $associationMapping['isOwningSide'] ? $associationMapping['joinColumns'] : [];
|
||||||
$newJoinColumns = array();
|
$newJoinColumns = array();
|
||||||
|
|
||||||
foreach ($joinColumns as $joinColumn) {
|
foreach ($joinColumns as $joinColumn) {
|
||||||
|
@ -1,4 +1,21 @@
|
|||||||
<?php
|
<?php
|
||||||
|
/*
|
||||||
|
* 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 MIT license. For more information, see
|
||||||
|
* <http://www.doctrine-project.org>.
|
||||||
|
*/
|
||||||
|
|
||||||
namespace Doctrine\ORM\Tools\Export;
|
namespace Doctrine\ORM\Tools\Export;
|
||||||
|
|
||||||
|
@ -1,14 +1,20 @@
|
|||||||
<?php
|
<?php
|
||||||
/**
|
/*
|
||||||
* Doctrine ORM
|
* 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.
|
||||||
*
|
*
|
||||||
* LICENSE
|
* This software consists of voluntary contributions made by many individuals
|
||||||
*
|
* and is licensed under the MIT license. For more information, see
|
||||||
* This source file is subject to the new BSD license that is bundled
|
* <http://www.doctrine-project.org>.
|
||||||
* with this package in the file LICENSE.txt.
|
|
||||||
* If you did not receive a copy of the license and are unable to
|
|
||||||
* obtain it through the world-wide-web, please send an email
|
|
||||||
* to kontakt@beberlei.de so I can send you a copy immediately.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace Doctrine\ORM\Tools\Pagination;
|
namespace Doctrine\ORM\Tools\Pagination;
|
||||||
|
@ -1,14 +1,20 @@
|
|||||||
<?php
|
<?php
|
||||||
/**
|
/*
|
||||||
* Doctrine ORM
|
* 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.
|
||||||
*
|
*
|
||||||
* LICENSE
|
* This software consists of voluntary contributions made by many individuals
|
||||||
*
|
* and is licensed under the MIT license. For more information, see
|
||||||
* This source file is subject to the new BSD license that is bundled
|
* <http://www.doctrine-project.org>.
|
||||||
* with this package in the file LICENSE.txt.
|
|
||||||
* If you did not receive a copy of the license and are unable to
|
|
||||||
* obtain it through the world-wide-web, please send an email
|
|
||||||
* to kontakt@beberlei.de so I can send you a copy immediately.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace Doctrine\ORM\Tools\Pagination;
|
namespace Doctrine\ORM\Tools\Pagination;
|
||||||
|
@ -1,14 +1,20 @@
|
|||||||
<?php
|
<?php
|
||||||
/**
|
/*
|
||||||
* Doctrine ORM
|
* 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.
|
||||||
*
|
*
|
||||||
* LICENSE
|
* This software consists of voluntary contributions made by many individuals
|
||||||
*
|
* and is licensed under the MIT license. For more information, see
|
||||||
* This source file is subject to the new BSD license that is bundled
|
* <http://www.doctrine-project.org>.
|
||||||
* with this package in the file LICENSE.txt.
|
|
||||||
* If you did not receive a copy of the license and are unable to
|
|
||||||
* obtain it through the world-wide-web, please send an email
|
|
||||||
* to kontakt@beberlei.de so I can send you a copy immediately.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace Doctrine\ORM\Tools\Pagination;
|
namespace Doctrine\ORM\Tools\Pagination;
|
||||||
@ -18,18 +24,9 @@ use Doctrine\DBAL\Platforms\OraclePlatform;
|
|||||||
use Doctrine\DBAL\Platforms\PostgreSqlPlatform;
|
use Doctrine\DBAL\Platforms\PostgreSqlPlatform;
|
||||||
use Doctrine\DBAL\Platforms\SQLAnywherePlatform;
|
use Doctrine\DBAL\Platforms\SQLAnywherePlatform;
|
||||||
use Doctrine\DBAL\Platforms\SQLServerPlatform;
|
use Doctrine\DBAL\Platforms\SQLServerPlatform;
|
||||||
use Doctrine\ORM\Query\AST\ArithmeticExpression;
|
|
||||||
use Doctrine\ORM\Query\AST\ArithmeticFactor;
|
|
||||||
use Doctrine\ORM\Query\AST\ArithmeticTerm;
|
|
||||||
use Doctrine\ORM\Query\AST\Literal;
|
|
||||||
use Doctrine\ORM\Query\AST\OrderByClause;
|
use Doctrine\ORM\Query\AST\OrderByClause;
|
||||||
use Doctrine\ORM\Query\AST\OrderByItem;
|
|
||||||
use Doctrine\ORM\Query\AST\PartialObjectExpression;
|
use Doctrine\ORM\Query\AST\PartialObjectExpression;
|
||||||
use Doctrine\ORM\Query\AST\PathExpression;
|
|
||||||
use Doctrine\ORM\Query\AST\SelectExpression;
|
use Doctrine\ORM\Query\AST\SelectExpression;
|
||||||
use Doctrine\ORM\Query\AST\SimpleArithmeticExpression;
|
|
||||||
use Doctrine\ORM\Query\Expr\OrderBy;
|
|
||||||
use Doctrine\ORM\Query\Expr\Select;
|
|
||||||
use Doctrine\ORM\Query\SqlWalker;
|
use Doctrine\ORM\Query\SqlWalker;
|
||||||
use Doctrine\ORM\Query\AST\SelectStatement;
|
use Doctrine\ORM\Query\AST\SelectStatement;
|
||||||
|
|
||||||
|
@ -1,26 +1,26 @@
|
|||||||
<?php
|
<?php
|
||||||
|
/*
|
||||||
/**
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
* Doctrine ORM
|
* "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.
|
||||||
*
|
*
|
||||||
* LICENSE
|
* This software consists of voluntary contributions made by many individuals
|
||||||
*
|
* and is licensed under the MIT license. For more information, see
|
||||||
* This source file is subject to the new BSD license that is bundled
|
* <http://www.doctrine-project.org>.
|
||||||
* with this package in the file LICENSE. This license can also be viewed
|
|
||||||
* at http://hobodave.com/license.txt
|
|
||||||
*
|
|
||||||
* @category DoctrineExtensions
|
|
||||||
* @package DoctrineExtensions\Paginate
|
|
||||||
* @author David Abdemoulaie <dave@hobodave.com>
|
|
||||||
* @copyright Copyright (c) 2010 David Abdemoulaie (http://hobodave.com/)
|
|
||||||
* @license http://hobodave.com/license.txt New BSD License
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace Doctrine\ORM\Tools\Pagination;
|
namespace Doctrine\ORM\Tools\Pagination;
|
||||||
|
|
||||||
use Doctrine\DBAL\Types\Type;
|
use Doctrine\DBAL\Types\Type;
|
||||||
use Doctrine\ORM\Mapping\ClassMetadataInfo;
|
use Doctrine\ORM\Mapping\ClassMetadataInfo;
|
||||||
use Doctrine\ORM\ORMException;
|
|
||||||
use Doctrine\ORM\Query;
|
use Doctrine\ORM\Query;
|
||||||
use Doctrine\ORM\Query\TreeWalkerAdapter;
|
use Doctrine\ORM\Query\TreeWalkerAdapter;
|
||||||
use Doctrine\ORM\Query\AST\Functions\IdentityFunction;
|
use Doctrine\ORM\Query\AST\Functions\IdentityFunction;
|
||||||
|
@ -1,18 +1,20 @@
|
|||||||
<?php
|
<?php
|
||||||
/**
|
/*
|
||||||
* Doctrine ORM
|
* 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.
|
||||||
*
|
*
|
||||||
* LICENSE
|
* This software consists of voluntary contributions made by many individuals
|
||||||
*
|
* and is licensed under the MIT license. For more information, see
|
||||||
* This source file is subject to the new BSD license that is bundled
|
* <http://www.doctrine-project.org>.
|
||||||
* with this package in the file LICENSE. This license can also be viewed
|
|
||||||
* at http://hobodave.com/license.txt
|
|
||||||
*
|
|
||||||
* @category DoctrineExtensions
|
|
||||||
* @package DoctrineExtensions\Paginate
|
|
||||||
* @author David Abdemoulaie <dave@hobodave.com>
|
|
||||||
* @copyright Copyright (c) 2010 David Abdemoulaie (http://hobodave.com/)
|
|
||||||
* @license http://hobodave.com/license.txt New BSD License
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace Doctrine\ORM\Tools\Pagination;
|
namespace Doctrine\ORM\Tools\Pagination;
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
* This software consists of voluntary contributions made by many individuals
|
* This software consists of voluntary contributions made by many individuals
|
||||||
* and is licensed under the MIT license. For more information, see
|
* and is licensed under the MIT license. For more information, see
|
||||||
* <http://www.doctrine-project.org>.
|
* <http://www.doctrine-project.org>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace Doctrine\ORM\Tools;
|
namespace Doctrine\ORM\Tools;
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
* This software consists of voluntary contributions made by many individuals
|
* This software consists of voluntary contributions made by many individuals
|
||||||
* and is licensed under the MIT license. For more information, see
|
* and is licensed under the MIT license. For more information, see
|
||||||
* <http://www.doctrine-project.org>.
|
* <http://www.doctrine-project.org>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace Doctrine\ORM\Tools;
|
namespace Doctrine\ORM\Tools;
|
||||||
|
|
||||||
|
@ -49,7 +49,6 @@ use Doctrine\ORM\Persisters\Entity\JoinedSubclassPersister;
|
|||||||
use Doctrine\ORM\Persisters\Collection\OneToManyPersister;
|
use Doctrine\ORM\Persisters\Collection\OneToManyPersister;
|
||||||
use Doctrine\ORM\Persisters\Collection\ManyToManyPersister;
|
use Doctrine\ORM\Persisters\Collection\ManyToManyPersister;
|
||||||
use Doctrine\ORM\Utility\IdentifierFlattener;
|
use Doctrine\ORM\Utility\IdentifierFlattener;
|
||||||
use Doctrine\ORM\Cache\AssociationCacheEntry;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The UnitOfWork is responsible for tracking changes to objects during an
|
* The UnitOfWork is responsible for tracking changes to objects during an
|
||||||
@ -1156,9 +1155,8 @@ class UnitOfWork implements PropertyChangedListener
|
|||||||
}
|
}
|
||||||
|
|
||||||
$joinColumns = reset($assoc['joinColumns']);
|
$joinColumns = reset($assoc['joinColumns']);
|
||||||
$isNullable = isset($joinColumns['nullable']) ? $joinColumns['nullable'] : false;
|
|
||||||
|
|
||||||
$calc->addDependency($targetClass->name, $class->name, $isNullable ? 0 : 1);
|
$calc->addDependency($targetClass->name, $class->name, (int)empty($joinColumns['nullable']));
|
||||||
|
|
||||||
// If the target class has mapped subclasses, these share the same dependency.
|
// If the target class has mapped subclasses, these share the same dependency.
|
||||||
if ( ! $targetClass->subClasses) {
|
if ( ! $targetClass->subClasses) {
|
||||||
@ -1281,7 +1279,7 @@ class UnitOfWork implements PropertyChangedListener
|
|||||||
$extraUpdate = array($entity, $changeset);
|
$extraUpdate = array($entity, $changeset);
|
||||||
|
|
||||||
if (isset($this->extraUpdates[$oid])) {
|
if (isset($this->extraUpdates[$oid])) {
|
||||||
list($ignored, $changeset2) = $this->extraUpdates[$oid];
|
list(, $changeset2) = $this->extraUpdates[$oid];
|
||||||
|
|
||||||
$extraUpdate = array($entity, $changeset + $changeset2);
|
$extraUpdate = array($entity, $changeset + $changeset2);
|
||||||
}
|
}
|
||||||
@ -1345,9 +1343,7 @@ class UnitOfWork implements PropertyChangedListener
|
|||||||
|
|
||||||
$this->removeFromIdentityMap($entity);
|
$this->removeFromIdentityMap($entity);
|
||||||
|
|
||||||
if (isset($this->entityUpdates[$oid])) {
|
|
||||||
unset($this->entityUpdates[$oid]);
|
unset($this->entityUpdates[$oid]);
|
||||||
}
|
|
||||||
|
|
||||||
if ( ! isset($this->entityDeletions[$oid])) {
|
if ( ! isset($this->entityDeletions[$oid])) {
|
||||||
$this->entityDeletions[$oid] = $entity;
|
$this->entityDeletions[$oid] = $entity;
|
||||||
@ -1402,12 +1398,13 @@ class UnitOfWork implements PropertyChangedListener
|
|||||||
public function addToIdentityMap($entity)
|
public function addToIdentityMap($entity)
|
||||||
{
|
{
|
||||||
$classMetadata = $this->em->getClassMetadata(get_class($entity));
|
$classMetadata = $this->em->getClassMetadata(get_class($entity));
|
||||||
$idHash = implode(' ', $this->entityIdentifiers[spl_object_hash($entity)]);
|
$identifier = $this->entityIdentifiers[spl_object_hash($entity)];
|
||||||
|
|
||||||
if ($idHash === '') {
|
if (empty($identifier) || in_array(null, $identifier, true)) {
|
||||||
throw ORMInvalidArgumentException::entityWithoutIdentity($classMetadata->name, $entity);
|
throw ORMInvalidArgumentException::entityWithoutIdentity($classMetadata->name, $entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$idHash = implode(' ', $identifier);
|
||||||
$className = $classMetadata->rootEntityName;
|
$className = $classMetadata->rootEntityName;
|
||||||
|
|
||||||
if (isset($this->identityMap[$className][$idHash])) {
|
if (isset($this->identityMap[$className][$idHash])) {
|
||||||
@ -1569,11 +1566,9 @@ class UnitOfWork implements PropertyChangedListener
|
|||||||
{
|
{
|
||||||
$stringIdHash = (string) $idHash;
|
$stringIdHash = (string) $idHash;
|
||||||
|
|
||||||
if (isset($this->identityMap[$rootClassName][$stringIdHash])) {
|
return isset($this->identityMap[$rootClassName][$stringIdHash])
|
||||||
return $this->identityMap[$rootClassName][$stringIdHash];
|
? $this->identityMap[$rootClassName][$stringIdHash]
|
||||||
}
|
: false;
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1797,7 +1792,7 @@ class UnitOfWork implements PropertyChangedListener
|
|||||||
* @throws ORMInvalidArgumentException If the entity instance is NEW.
|
* @throws ORMInvalidArgumentException If the entity instance is NEW.
|
||||||
* @throws EntityNotFoundException
|
* @throws EntityNotFoundException
|
||||||
*/
|
*/
|
||||||
private function doMerge($entity, array &$visited, $prevManagedCopy = null, $assoc = null)
|
private function doMerge($entity, array &$visited, $prevManagedCopy = null, array $assoc = [])
|
||||||
{
|
{
|
||||||
$oid = spl_object_hash($entity);
|
$oid = spl_object_hash($entity);
|
||||||
|
|
||||||
@ -2391,17 +2386,8 @@ class UnitOfWork implements PropertyChangedListener
|
|||||||
$this->visitedCollections =
|
$this->visitedCollections =
|
||||||
$this->orphanRemovals = array();
|
$this->orphanRemovals = array();
|
||||||
} else {
|
} else {
|
||||||
$visited = array();
|
$this->clearIdentityMapForEntityName($entityName);
|
||||||
|
$this->clearEntityInsertionsForEntityName($entityName);
|
||||||
foreach ($this->identityMap as $className => $entities) {
|
|
||||||
if ($className !== $entityName) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach ($entities as $entity) {
|
|
||||||
$this->doDetach($entity, $visited, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->evm->hasListeners(Events::onClear)) {
|
if ($this->evm->hasListeners(Events::onClear)) {
|
||||||
@ -2455,9 +2441,7 @@ class UnitOfWork implements PropertyChangedListener
|
|||||||
|
|
||||||
// TODO: if $coll is already scheduled for recreation ... what to do?
|
// TODO: if $coll is already scheduled for recreation ... what to do?
|
||||||
// Just remove $coll from the scheduled recreations?
|
// Just remove $coll from the scheduled recreations?
|
||||||
if (isset($this->collectionUpdates[$coid])) {
|
|
||||||
unset($this->collectionUpdates[$coid]);
|
unset($this->collectionUpdates[$coid]);
|
||||||
}
|
|
||||||
|
|
||||||
$this->collectionDeletions[$coid] = $coll;
|
$this->collectionDeletions[$coid] = $coll;
|
||||||
}
|
}
|
||||||
@ -2864,11 +2848,9 @@ class UnitOfWork implements PropertyChangedListener
|
|||||||
{
|
{
|
||||||
$oid = spl_object_hash($entity);
|
$oid = spl_object_hash($entity);
|
||||||
|
|
||||||
if (isset($this->originalEntityData[$oid])) {
|
return isset($this->originalEntityData[$oid])
|
||||||
return $this->originalEntityData[$oid];
|
? $this->originalEntityData[$oid]
|
||||||
}
|
: [];
|
||||||
|
|
||||||
return array();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -2954,11 +2936,9 @@ class UnitOfWork implements PropertyChangedListener
|
|||||||
{
|
{
|
||||||
$idHash = implode(' ', (array) $id);
|
$idHash = implode(' ', (array) $id);
|
||||||
|
|
||||||
if (isset($this->identityMap[$rootClassName][$idHash])) {
|
return isset($this->identityMap[$rootClassName][$idHash])
|
||||||
return $this->identityMap[$rootClassName][$idHash];
|
? $this->identityMap[$rootClassName][$idHash]
|
||||||
}
|
: false;
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -2995,7 +2975,7 @@ class UnitOfWork implements PropertyChangedListener
|
|||||||
*/
|
*/
|
||||||
public function size()
|
public function size()
|
||||||
{
|
{
|
||||||
$countArray = array_map(function ($item) { return count($item); }, $this->identityMap);
|
$countArray = array_map('count', $this->identityMap);
|
||||||
|
|
||||||
return array_sum($countArray);
|
return array_sum($countArray);
|
||||||
}
|
}
|
||||||
@ -3424,8 +3404,6 @@ class UnitOfWork implements PropertyChangedListener
|
|||||||
);
|
);
|
||||||
$managedCol->setOwner($managedCopy, $assoc2);
|
$managedCol->setOwner($managedCopy, $assoc2);
|
||||||
$prop->setValue($managedCopy, $managedCol);
|
$prop->setValue($managedCopy, $managedCol);
|
||||||
|
|
||||||
$this->originalEntityData[spl_object_hash($entity)][$name] = $managedCol;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($assoc2['isCascadeMerge']) {
|
if ($assoc2['isCascadeMerge']) {
|
||||||
@ -3464,4 +3442,33 @@ class UnitOfWork implements PropertyChangedListener
|
|||||||
{
|
{
|
||||||
$this->hydrationCompleteHandler->hydrationComplete();
|
$this->hydrationCompleteHandler->hydrationComplete();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $entityName
|
||||||
|
*/
|
||||||
|
private function clearIdentityMapForEntityName($entityName)
|
||||||
|
{
|
||||||
|
if (! isset($this->identityMap[$entityName])) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$visited = [];
|
||||||
|
|
||||||
|
foreach ($this->identityMap[$entityName] as $entity) {
|
||||||
|
$this->doDetach($entity, $visited, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $entityName
|
||||||
|
*/
|
||||||
|
private function clearEntityInsertionsForEntityName($entityName)
|
||||||
|
{
|
||||||
|
foreach ($this->entityInsertions as $hash => $entity) {
|
||||||
|
// note: performance optimization - `instanceof` is much faster than a function call
|
||||||
|
if ($entity instanceof $entityName && get_class($entity) === $entityName) {
|
||||||
|
unset($this->entityInsertions[$hash]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,21 +1,4 @@
|
|||||||
<?php
|
<?php
|
||||||
/*
|
|
||||||
* 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 MIT license. For more information, see
|
|
||||||
* <http://www.doctrine-project.org>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace Doctrine\Tests\DbalTypes;
|
namespace Doctrine\Tests\DbalTypes;
|
||||||
|
|
||||||
|
@ -1,21 +1,4 @@
|
|||||||
<?php
|
<?php
|
||||||
/*
|
|
||||||
* 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 MIT license. For more information, see
|
|
||||||
* <http://www.doctrine-project.org>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace Doctrine\Tests\DbalTypes;
|
namespace Doctrine\Tests\DbalTypes;
|
||||||
|
|
||||||
|
@ -40,7 +40,7 @@ class CacheMetadataListener
|
|||||||
*
|
*
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
private function isVisited(ClassMetaData $metadata)
|
private function isVisited(ClassMetadata $metadata)
|
||||||
{
|
{
|
||||||
return isset($this->enabledItems[$metadata->getName()]);
|
return isset($this->enabledItems[$metadata->getName()]);
|
||||||
}
|
}
|
||||||
@ -48,7 +48,7 @@ class CacheMetadataListener
|
|||||||
/**
|
/**
|
||||||
* @param ClassMetadata $metadata
|
* @param ClassMetadata $metadata
|
||||||
*/
|
*/
|
||||||
private function recordVisit(ClassMetaData $metadata)
|
private function recordVisit(ClassMetadata $metadata)
|
||||||
{
|
{
|
||||||
$this->enabledItems[$metadata->getName()] = true;
|
$this->enabledItems[$metadata->getName()] = true;
|
||||||
}
|
}
|
||||||
|
@ -2,10 +2,12 @@
|
|||||||
|
|
||||||
namespace Doctrine\Tests\Mocks;
|
namespace Doctrine\Tests\Mocks;
|
||||||
|
|
||||||
|
use Doctrine\ORM\Mapping\ClassMetadata;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mock class for ClassMetadata.
|
* Mock class for ClassMetadata.
|
||||||
*/
|
*/
|
||||||
class ClassMetadataMock extends \Doctrine\ORM\Mapping\ClassMetadata
|
class ClassMetadataMock extends ClassMetadata
|
||||||
{
|
{
|
||||||
/* Mock API */
|
/* Mock API */
|
||||||
|
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Doctrine\Tests\Mocks;
|
namespace Doctrine\Tests\Mocks;
|
||||||
|
use Doctrine\DBAL\Connection;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mock class for Connection.
|
* Mock class for Connection.
|
||||||
*/
|
*/
|
||||||
class ConnectionMock extends \Doctrine\DBAL\Connection
|
class ConnectionMock extends Connection
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @var mixed
|
* @var mixed
|
||||||
|
@ -2,10 +2,12 @@
|
|||||||
|
|
||||||
namespace Doctrine\Tests\Mocks;
|
namespace Doctrine\Tests\Mocks;
|
||||||
|
|
||||||
|
use Doctrine\DBAL\Platforms\AbstractPlatform;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mock class for DatabasePlatform.
|
* Mock class for DatabasePlatform.
|
||||||
*/
|
*/
|
||||||
class DatabasePlatformMock extends \Doctrine\DBAL\Platforms\AbstractPlatform
|
class DatabasePlatformMock extends AbstractPlatform
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @var string
|
* @var string
|
||||||
|
@ -2,10 +2,12 @@
|
|||||||
|
|
||||||
namespace Doctrine\Tests\Mocks;
|
namespace Doctrine\Tests\Mocks;
|
||||||
|
|
||||||
|
use Doctrine\DBAL\Driver\Connection;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mock class for DriverConnection.
|
* Mock class for DriverConnection.
|
||||||
*/
|
*/
|
||||||
class DriverConnectionMock implements \Doctrine\DBAL\Driver\Connection
|
class DriverConnectionMock implements Connection
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @var \Doctrine\DBAL\Driver\Statement
|
* @var \Doctrine\DBAL\Driver\Statement
|
||||||
|
@ -2,10 +2,15 @@
|
|||||||
|
|
||||||
namespace Doctrine\Tests\Mocks;
|
namespace Doctrine\Tests\Mocks;
|
||||||
|
|
||||||
|
use Doctrine\DBAL\Connection;
|
||||||
|
use Doctrine\DBAL\Driver;
|
||||||
|
use Doctrine\DBAL\Platforms\AbstractPlatform;
|
||||||
|
use Doctrine\DBAL\Schema\AbstractSchemaManager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mock class for Driver.
|
* Mock class for Driver.
|
||||||
*/
|
*/
|
||||||
class DriverMock implements \Doctrine\DBAL\Driver
|
class DriverMock implements Driver
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @var \Doctrine\DBAL\Platforms\AbstractPlatform|null
|
* @var \Doctrine\DBAL\Platforms\AbstractPlatform|null
|
||||||
@ -39,7 +44,7 @@ class DriverMock implements \Doctrine\DBAL\Driver
|
|||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
public function getSchemaManager(\Doctrine\DBAL\Connection $conn)
|
public function getSchemaManager(Connection $conn)
|
||||||
{
|
{
|
||||||
if ($this->_schemaManagerMock == null) {
|
if ($this->_schemaManagerMock == null) {
|
||||||
return new SchemaManagerMock($conn);
|
return new SchemaManagerMock($conn);
|
||||||
@ -55,7 +60,7 @@ class DriverMock implements \Doctrine\DBAL\Driver
|
|||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function setDatabasePlatform(\Doctrine\DBAL\Platforms\AbstractPlatform $platform)
|
public function setDatabasePlatform(AbstractPlatform $platform)
|
||||||
{
|
{
|
||||||
$this->_platformMock = $platform;
|
$this->_platformMock = $platform;
|
||||||
}
|
}
|
||||||
@ -65,7 +70,7 @@ class DriverMock implements \Doctrine\DBAL\Driver
|
|||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function setSchemaManager(\Doctrine\DBAL\Schema\AbstractSchemaManager $sm)
|
public function setSchemaManager(AbstractSchemaManager $sm)
|
||||||
{
|
{
|
||||||
$this->_schemaManagerMock = $sm;
|
$this->_schemaManagerMock = $sm;
|
||||||
}
|
}
|
||||||
@ -81,7 +86,7 @@ class DriverMock implements \Doctrine\DBAL\Driver
|
|||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
public function getDatabase(\Doctrine\DBAL\Connection $conn)
|
public function getDatabase(Connection $conn)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1,32 +1,15 @@
|
|||||||
<?php
|
<?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\Tests\Mocks;
|
namespace Doctrine\Tests\Mocks;
|
||||||
|
|
||||||
use Doctrine\ORM\Proxy\ProxyFactory;
|
use Doctrine\Common\EventManager;
|
||||||
|
use Doctrine\ORM\Configuration;
|
||||||
|
use Doctrine\ORM\EntityManager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Special EntityManager mock used for testing purposes.
|
* Special EntityManager mock used for testing purposes.
|
||||||
*/
|
*/
|
||||||
class EntityManagerMock extends \Doctrine\ORM\EntityManager
|
class EntityManagerMock extends EntityManager
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @var \Doctrine\ORM\UnitOfWork|null
|
* @var \Doctrine\ORM\UnitOfWork|null
|
||||||
@ -83,17 +66,16 @@ class EntityManagerMock extends \Doctrine\ORM\EntityManager
|
|||||||
*
|
*
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
public static function create($conn, \Doctrine\ORM\Configuration $config = null,
|
public static function create($conn, Configuration $config = null, EventManager $eventManager = null)
|
||||||
\Doctrine\Common\EventManager $eventManager = null)
|
|
||||||
{
|
{
|
||||||
if (null === $config) {
|
if (null === $config) {
|
||||||
$config = new \Doctrine\ORM\Configuration();
|
$config = new Configuration();
|
||||||
$config->setProxyDir(__DIR__ . '/../Proxies');
|
$config->setProxyDir(__DIR__ . '/../Proxies');
|
||||||
$config->setProxyNamespace('Doctrine\Tests\Proxies');
|
$config->setProxyNamespace('Doctrine\Tests\Proxies');
|
||||||
$config->setMetadataDriverImpl($config->newDefaultAnnotationDriver(array(), true));
|
$config->setMetadataDriverImpl($config->newDefaultAnnotationDriver(array(), true));
|
||||||
}
|
}
|
||||||
if (null === $eventManager) {
|
if (null === $eventManager) {
|
||||||
$eventManager = new \Doctrine\Common\EventManager();
|
$eventManager = new EventManager();
|
||||||
}
|
}
|
||||||
|
|
||||||
return new EntityManagerMock($conn, $config, $eventManager);
|
return new EntityManagerMock($conn, $config, $eventManager);
|
||||||
|
@ -3,11 +3,13 @@
|
|||||||
namespace Doctrine\Tests\Mocks;
|
namespace Doctrine\Tests\Mocks;
|
||||||
|
|
||||||
use Doctrine\Common\Collections\Criteria;
|
use Doctrine\Common\Collections\Criteria;
|
||||||
|
use Doctrine\ORM\Mapping\ClassMetadata;
|
||||||
|
use Doctrine\ORM\Persisters\Entity\BasicEntityPersister;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* EntityPersister implementation used for mocking during tests.
|
* EntityPersister implementation used for mocking during tests.
|
||||||
*/
|
*/
|
||||||
class EntityPersisterMock extends \Doctrine\ORM\Persisters\Entity\BasicEntityPersister
|
class EntityPersisterMock extends BasicEntityPersister
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @var array
|
* @var array
|
||||||
@ -52,7 +54,7 @@ class EntityPersisterMock extends \Doctrine\ORM\Persisters\Entity\BasicEntityPer
|
|||||||
public function addInsert($entity)
|
public function addInsert($entity)
|
||||||
{
|
{
|
||||||
$this->inserts[] = $entity;
|
$this->inserts[] = $entity;
|
||||||
if ( ! is_null($this->mockIdGeneratorType) && $this->mockIdGeneratorType == \Doctrine\ORM\Mapping\ClassMetadata::GENERATOR_TYPE_IDENTITY
|
if ( ! is_null($this->mockIdGeneratorType) && $this->mockIdGeneratorType == ClassMetadata::GENERATOR_TYPE_IDENTITY
|
||||||
|| $this->class->isIdGeneratorIdentity()) {
|
|| $this->class->isIdGeneratorIdentity()) {
|
||||||
$id = $this->identityColumnValueCounter++;
|
$id = $this->identityColumnValueCounter++;
|
||||||
$this->postInsertIds[] = array(
|
$this->postInsertIds[] = array(
|
||||||
|
@ -2,13 +2,15 @@
|
|||||||
|
|
||||||
namespace Doctrine\Tests\Mocks;
|
namespace Doctrine\Tests\Mocks;
|
||||||
|
|
||||||
|
use Doctrine\DBAL\Driver\Statement;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class is a mock of the Statement interface that can be passed in to the Hydrator
|
* This class is a mock of the Statement interface that can be passed in to the Hydrator
|
||||||
* to test the hydration standalone with faked result sets.
|
* to test the hydration standalone with faked result sets.
|
||||||
*
|
*
|
||||||
* @author Roman Borschel <roman@code-factory.org>
|
* @author Roman Borschel <roman@code-factory.org>
|
||||||
*/
|
*/
|
||||||
class HydratorMockStatement implements \IteratorAggregate, \Doctrine\DBAL\Driver\Statement
|
class HydratorMockStatement implements \IteratorAggregate, Statement
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @var array
|
* @var array
|
||||||
|
@ -2,15 +2,18 @@
|
|||||||
|
|
||||||
namespace Doctrine\Tests\Mocks;
|
namespace Doctrine\Tests\Mocks;
|
||||||
|
|
||||||
|
use Doctrine\Common\Persistence\Mapping\Driver\MappingDriver;
|
||||||
|
use Doctrine\Common\Persistence\Mapping\ClassMetadata;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mock class for MappingDriver.
|
* Mock class for MappingDriver.
|
||||||
*/
|
*/
|
||||||
class MetadataDriverMock implements \Doctrine\Common\Persistence\Mapping\Driver\MappingDriver
|
class MetadataDriverMock implements MappingDriver
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
public function loadMetadataForClass($className, \Doctrine\Common\Persistence\Mapping\ClassMetadata $metadata)
|
public function loadMetadataForClass($className, ClassMetadata $metadata)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,10 +2,12 @@
|
|||||||
|
|
||||||
namespace Doctrine\Tests\Mocks;
|
namespace Doctrine\Tests\Mocks;
|
||||||
|
|
||||||
|
use Doctrine\ORM\Query\TreeWalkerAdapter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mock class for TreeWalker.
|
* Mock class for TreeWalker.
|
||||||
*/
|
*/
|
||||||
class MockTreeWalker extends \Doctrine\ORM\Query\TreeWalkerAdapter
|
class MockTreeWalker extends TreeWalkerAdapter
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
|
@ -2,15 +2,18 @@
|
|||||||
|
|
||||||
namespace Doctrine\Tests\Mocks;
|
namespace Doctrine\Tests\Mocks;
|
||||||
|
|
||||||
|
use Doctrine\DBAL\Connection;
|
||||||
|
use Doctrine\DBAL\Schema\AbstractSchemaManager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mock class for AbstractSchemaManager.
|
* Mock class for AbstractSchemaManager.
|
||||||
*/
|
*/
|
||||||
class SchemaManagerMock extends \Doctrine\DBAL\Schema\AbstractSchemaManager
|
class SchemaManagerMock extends AbstractSchemaManager
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @param \Doctrine\DBAL\Connection $conn
|
* @param \Doctrine\DBAL\Connection $conn
|
||||||
*/
|
*/
|
||||||
public function __construct(\Doctrine\DBAL\Connection $conn)
|
public function __construct(Connection $conn)
|
||||||
{
|
{
|
||||||
parent::__construct($conn);
|
parent::__construct($conn);
|
||||||
}
|
}
|
||||||
|
@ -3,11 +3,12 @@
|
|||||||
namespace Doctrine\Tests\Mocks;
|
namespace Doctrine\Tests\Mocks;
|
||||||
|
|
||||||
use Doctrine\ORM\EntityManager;
|
use Doctrine\ORM\EntityManager;
|
||||||
|
use Doctrine\ORM\Id\SequenceGenerator;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mock class for SequenceGenerator.
|
* Mock class for SequenceGenerator.
|
||||||
*/
|
*/
|
||||||
class SequenceMock extends \Doctrine\ORM\Id\SequenceGenerator
|
class SequenceMock extends SequenceGenerator
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @var int
|
* @var int
|
||||||
|
@ -1,10 +1,4 @@
|
|||||||
<?php
|
<?php
|
||||||
/**
|
|
||||||
* Created by PhpStorm.
|
|
||||||
* User: avasilenko
|
|
||||||
* Date: 24/04/15
|
|
||||||
* Time: 19:01
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace Doctrine\Tests\Mocks;
|
namespace Doctrine\Tests\Mocks;
|
||||||
|
|
||||||
|
@ -2,12 +2,14 @@
|
|||||||
|
|
||||||
namespace Doctrine\Tests\Mocks;
|
namespace Doctrine\Tests\Mocks;
|
||||||
|
|
||||||
|
use Doctrine\DBAL\Driver\Statement;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class is a mock of the Statement interface.
|
* This class is a mock of the Statement interface.
|
||||||
*
|
*
|
||||||
* @author Alexander <iam.asm89@gmail.com>
|
* @author Alexander <iam.asm89@gmail.com>
|
||||||
*/
|
*/
|
||||||
class StatementMock implements \IteratorAggregate, \Doctrine\DBAL\Driver\Statement
|
class StatementMock implements \IteratorAggregate, Statement
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
|
@ -1,23 +1,4 @@
|
|||||||
<?php
|
<?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\Tests\Mocks;
|
namespace Doctrine\Tests\Mocks;
|
||||||
|
|
||||||
|
@ -2,10 +2,12 @@
|
|||||||
|
|
||||||
namespace Doctrine\Tests\Mocks;
|
namespace Doctrine\Tests\Mocks;
|
||||||
|
|
||||||
|
use Doctrine\ORM\UnitOfWork;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mock class for UnitOfWork.
|
* Mock class for UnitOfWork.
|
||||||
*/
|
*/
|
||||||
class UnitOfWorkMock extends \Doctrine\ORM\UnitOfWork
|
class UnitOfWorkMock extends UnitOfWork
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @var array
|
* @var array
|
||||||
|
@ -1,8 +1,4 @@
|
|||||||
<?php
|
<?php
|
||||||
/*
|
|
||||||
* To change this template, choose Tools | Templates
|
|
||||||
* and open the template in the editor.
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace Doctrine\Tests\Models\CMS;
|
namespace Doctrine\Tests\Models\CMS;
|
||||||
|
|
||||||
|
@ -1,8 +1,4 @@
|
|||||||
<?php
|
<?php
|
||||||
/*
|
|
||||||
* To change this template, choose Tools | Templates
|
|
||||||
* and open the template in the editor.
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace Doctrine\Tests\Models\CMS;
|
namespace Doctrine\Tests\Models\CMS;
|
||||||
|
|
||||||
|
@ -14,13 +14,8 @@ class Action
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @Id
|
* @Id
|
||||||
* @GeneratedValue
|
* @Column(type="string")
|
||||||
* @Column(type="integer")
|
* @GeneratedValue(strategy="NONE")
|
||||||
*/
|
|
||||||
public $id;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @Column
|
|
||||||
*/
|
*/
|
||||||
public $name;
|
public $name;
|
||||||
|
|
||||||
|
@ -20,14 +20,14 @@ class ComplexAction
|
|||||||
/**
|
/**
|
||||||
* @Id
|
* @Id
|
||||||
* @OneToOne(targetEntity="Action", cascade={"persist", "remove"})
|
* @OneToOne(targetEntity="Action", cascade={"persist", "remove"})
|
||||||
* @JoinColumn(name="action1_id", referencedColumnName="id")
|
* @JoinColumn(name="action1_name", referencedColumnName="name")
|
||||||
*/
|
*/
|
||||||
public $action1;
|
public $action1;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Id
|
* @Id
|
||||||
* @OneToOne(targetEntity="Action", cascade={"persist", "remove"})
|
* @OneToOne(targetEntity="Action", cascade={"persist", "remove"})
|
||||||
* @JoinColumn(name="action2_id", referencedColumnName="id")
|
* @JoinColumn(name="action2_name", referencedColumnName="name")
|
||||||
*/
|
*/
|
||||||
public $action2;
|
public $action2;
|
||||||
|
|
||||||
|
@ -36,7 +36,7 @@ class Token
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @ManyToOne(targetEntity="Action", cascade={"persist", "remove"}, inversedBy="tokens")
|
* @ManyToOne(targetEntity="Action", cascade={"persist", "remove"}, inversedBy="tokens")
|
||||||
* @JoinColumn(name="action_id", referencedColumnName="id")
|
* @JoinColumn(name="action_name", referencedColumnName="name")
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
public $action;
|
public $action;
|
||||||
@ -44,8 +44,8 @@ class Token
|
|||||||
/**
|
/**
|
||||||
* @ManyToOne(targetEntity="ComplexAction", cascade={"persist", "remove"}, inversedBy="tokens")
|
* @ManyToOne(targetEntity="ComplexAction", cascade={"persist", "remove"}, inversedBy="tokens")
|
||||||
* @JoinColumns({
|
* @JoinColumns({
|
||||||
* @JoinColumn(name="complex_action1_id", referencedColumnName="action1_id"),
|
* @JoinColumn(name="complex_action1_name", referencedColumnName="action1_name"),
|
||||||
* @JoinColumn(name="complex_action2_id", referencedColumnName="action2_id")
|
* @JoinColumn(name="complex_action2_name", referencedColumnName="action2_name")
|
||||||
* })
|
* })
|
||||||
* @var ComplexAction
|
* @var ComplexAction
|
||||||
*/
|
*/
|
||||||
|
@ -1,21 +1,4 @@
|
|||||||
<?php
|
<?php
|
||||||
/*
|
|
||||||
* 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 MIT license. For more information, see
|
|
||||||
* <http://www.doctrine-project.org>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace Doctrine\Tests\Models\CustomType;
|
namespace Doctrine\Tests\Models\CustomType;
|
||||||
|
|
||||||
|
@ -1,21 +1,4 @@
|
|||||||
<?php
|
<?php
|
||||||
/*
|
|
||||||
* 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 MIT license. For more information, see
|
|
||||||
* <http://www.doctrine-project.org>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace Doctrine\Tests\Models\CustomType;
|
namespace Doctrine\Tests\Models\CustomType;
|
||||||
|
|
||||||
|
@ -1,23 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
|
||||||
* 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\Tests\Models\DDC1476;
|
namespace Doctrine\Tests\Models\DDC1476;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -20,7 +20,7 @@ class DDC2504RootClass
|
|||||||
public $id;
|
public $id;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var Doctrine\Tests\Models\DDC\DDC2504OtherClass
|
* @var \Doctrine\Tests\Models\DDC2504\DDC2504OtherClass
|
||||||
*
|
*
|
||||||
* @ManyToOne(targetEntity="DDC2504OtherClass", inversedBy="childClasses")
|
* @ManyToOne(targetEntity="DDC2504OtherClass", inversedBy="childClasses")
|
||||||
*/
|
*/
|
||||||
|
@ -10,7 +10,7 @@ class DDC3293User
|
|||||||
protected $id;
|
protected $id;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var Doctrine\Tests\Models\DDC3293\DDC3293Address
|
* @var \Doctrine\Tests\Models\DDC3293\DDC3293Address
|
||||||
*/
|
*/
|
||||||
protected $address;
|
protected $address;
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,7 @@ class DDC3293UserPrefixed
|
|||||||
protected $id;
|
protected $id;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var Doctrine\Tests\Models\DDC3293\DDC3293Address
|
* @var \Doctrine\Tests\Models\DDC3293\DDC3293Address
|
||||||
*/
|
*/
|
||||||
protected $address;
|
protected $address;
|
||||||
}
|
}
|
||||||
|
@ -2,8 +2,6 @@
|
|||||||
|
|
||||||
namespace Doctrine\Tests\Models\DDC3579;
|
namespace Doctrine\Tests\Models\DDC3579;
|
||||||
|
|
||||||
use Doctrine\Common\Collections\ArrayCollection;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Entity
|
* @Entity
|
||||||
* @AssociationOverrides({
|
* @AssociationOverrides({
|
||||||
|
@ -1,12 +1,13 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Marc Pantel <pantel.m@gmail.com>
|
|
||||||
*/
|
|
||||||
namespace Doctrine\Tests\Models\DDC3711;
|
namespace Doctrine\Tests\Models\DDC3711;
|
||||||
|
|
||||||
use Doctrine\Common\Collections\ArrayCollection;
|
use Doctrine\Common\Collections\ArrayCollection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Marc Pantel <pantel.m@gmail.com>
|
||||||
|
*/
|
||||||
class DDC3711EntityA
|
class DDC3711EntityA
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
|
@ -1,12 +1,13 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Marc Pantel <pantel.m@gmail.com>
|
|
||||||
*/
|
|
||||||
namespace Doctrine\Tests\Models\DDC3711;
|
namespace Doctrine\Tests\Models\DDC3711;
|
||||||
|
|
||||||
use Doctrine\Common\Collections\ArrayCollection;
|
use Doctrine\Common\Collections\ArrayCollection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Marc Pantel <pantel.m@gmail.com>
|
||||||
|
*/
|
||||||
class DDC3711EntityB
|
class DDC3711EntityB
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
|
@ -1,23 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
|
||||||
* 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\Tests\Models\DDC753;
|
namespace Doctrine\Tests\Models\DDC753;
|
||||||
|
|
||||||
use Doctrine\ORM\EntityRepository;
|
use Doctrine\ORM\EntityRepository;
|
||||||
|
@ -1,23 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
|
||||||
* 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\Tests\Models\DDC753;
|
namespace Doctrine\Tests\Models\DDC753;
|
||||||
|
|
||||||
use Doctrine\ORM\EntityRepository;
|
use Doctrine\ORM\EntityRepository;
|
||||||
|
@ -1,23 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
|
||||||
* 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\Tests\Models\DDC753;
|
namespace Doctrine\Tests\Models\DDC753;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,23 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
|
||||||
* 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\Tests\Models\DDC753;
|
namespace Doctrine\Tests\Models\DDC753;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,23 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
|
||||||
* 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\Tests\Models\DDC753;
|
namespace Doctrine\Tests\Models\DDC753;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,27 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
|
||||||
* 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\Tests\Models\DDC753;
|
namespace Doctrine\Tests\Models\DDC753;
|
||||||
|
|
||||||
use Doctrine\ORM\EntityRepository;
|
|
||||||
|
|
||||||
class DDC753InvalidRepository
|
class DDC753InvalidRepository
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -1,23 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
|
||||||
* 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\Tests\Models\DDC869;
|
namespace Doctrine\Tests\Models\DDC869;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user